python實現(xiàn)堆棧與隊列的方法
專注于為中小企業(yè)提供成都網(wǎng)站制作、成都網(wǎng)站建設(shè)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)武穴免費做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了上千企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。
本文實例講述了python實現(xiàn)堆棧與隊列的方法。分享給大家供大家參考。具體分析如下:
1、python實現(xiàn)堆棧,可先將Stack類寫入文件stack.py,在其它程序文件中使用from stack import Stack,然后就可以使用堆棧了。
stack.py的程序:
代碼如下:class Stack():
def __init__(self,size):
self.size=size;
self.stack=[];
self.top=-1;
def push(self,ele): #入棧之前檢查棧是否已滿
if self.isfull():
raise exception("out of range");
else:
self.stack.append(ele);
self.top=self.top+1;
def pop(self): # 出棧之前檢查棧是否為空
if self.isempty():
raise exception("stack is empty");
else:
self.top=self.top-1;
return self.stack.pop();
def isfull(self):
return self.top+1==self.size;
def isempty(self):
return self.top==-1;
再寫一個程序文件,stacktest.py,使用棧,內(nèi)容如下:
代碼如下:#!/usr/bin/python
from stack import Stack
s=Stack(20);
for i in range(3):
s.push(i);
s.pop()
print s.isempty();
2、python 實現(xiàn)隊列:
復(fù)制代碼代碼如下:class Queue():
def __init__(self,size):
self.size=size;
self.front=-1;
self.rear=-1;
self.queue=[];
def enqueue(self,ele): #入隊操作
if self.isfull():
raise exception("queue is full");
else:
self.queue.append(ele);
self.rear=self.rear+1;
def dequeue(self): #出隊操作
if self.isempty():
raise exception("queue is empty");
else:
self.front=self.front+1;
return self.queue[self.front];
def isfull(self):
return self.rear-self.front+1==self.size;
def isempty(self):
return self.front==self.rear;
q=Queue(10);
for i in range(3):
q.enqueue(i);
print q.dequeue();
print q.isempty();
希望本文所述對大家的Python程序設(shè)計有所幫助。
concat()連接兩個或更多的數(shù)組,并返回結(jié)果。
join()把數(shù)組的所有元素放入一個字符串。元素通過指定的分隔符進(jìn)行分隔。
pop()刪除并返回數(shù)組的最后一個元素
push()向數(shù)組的末尾添加一個或更多元素,并返回新的長度。
reverse()顛倒數(shù)組中元素的順序。
shift()刪除并返回數(shù)組的第一個元素
slice()從某個已有的數(shù)組返回選定的元素
sort()對數(shù)組的元素進(jìn)行排序
splice()刪除元素,并向數(shù)組添加新元素。
tosource()返回該對象的源代碼
tostring()把數(shù)組轉(zhuǎn)換為字符串,并返回結(jié)果。
tolocalestring()把數(shù)組轉(zhuǎn)換為本地數(shù)組,并返回結(jié)果。
unshift()向數(shù)組的開頭添加一個或更多元素,并返回新的長度。
valueof()返回數(shù)組對象的原始值
include malloc.h #include stdio.h #include ctype.h//判斷是否為字符的函數(shù)的頭文件 #define maxsize 100 typedef int elemtype; typedef struct sqstack sqstack;//由于sqstack不是一個類型 而struct sqstack才是 char ch[7]=;//把符號轉(zhuǎn)換成一個字符數(shù)組 int f1[7]=;//棧內(nèi)元素優(yōu)先級 int f2[7]=;//棧外的元素優(yōu)先級 struct sqstack { elemtype stack[maxsize]; int top; }; void Initstack(sqstack *s) { s-top=0; } void Push(sqstack *s,elemtype x) { if(s-top==maxsize-1) printf("Overflow\n"); else { s-top++; s-stack[s-top]=x; } } void Pop(sqstack *s,elemtype *x) { if(s-top==0) printf("underflow\n"); else { *x=s-stack[s-top]; s-top--; } } elemtype Gettop(sqstack s) { if(s.top==0) { printf("underflow\n"); return 0; } else return s.stack[s.top]; } elemtype f(char c) { switch(c) { case '+': return 0; case '-': return 1; case '*': return 2; case '/': return 3; case '(': return 4; case ')': return 5; default: return 6; } } char precede(char c1,char c2) { int i1=f(c1); int i2=f(c2);//把字符變成數(shù)字 if(f1[i1]f2[i2])//通過原來設(shè)定找到優(yōu)先級 return ''; else if(f1[i1]f2[i2]) return ''; else return '='; } int Operate(elemtype a,elemtype theta,elemtype b) { int sum; switch(theta) { case 0: sum=a+b; break; case 1: sum=a-b; break; case 2: sum=a*b; break; default: sum=a/b; } return sum; } EvaluateExpression() { char c; int i=0,sum=0; int k=1,j=1;//設(shè)置了開關(guān)變量 elemtype x,theta,a,b; sqstack OPTR,OPND; Initstack(OPTR); Push(OPTR,f('#'));//0壓入棧 Initstack(OPND); c=getchar(); if(c==ch[2]||c==ch[3]||c==ch[5]||c==ch[6])//先對+和-的情況忽略和左括號的情況 { printf("錯誤1 \n"); k=0; return 0; } if(c==ch[0]) c=getchar();//如果是+,把它覆蓋 if(c==ch[1]) { j=0; c=getchar();//也把-號覆蓋 } while(c!='#'||ch[Gettop(OPTR)]!='#') { if(isdigit(c)) { sum=0; while(isdigit(c)) { if(!j) { sum=sum*10-(c-'0');//實現(xiàn)了數(shù)字串前面有負(fù)號(之前是:sum=-(sum*10)-(c-'0')結(jié)果是-12+13=21) } else sum=sum*10+(c-'0'); c=getchar(); } Push(OPND,sum);//如果還是數(shù)字先不壓棧,把數(shù)字串轉(zhuǎn)化成十進(jìn)制數(shù)字再壓棧 j=1; } else if(k) { switch(precede(ch[Gettop(OPTR)],c)) { case'': Push(OPTR,f(c));//把它們整型化 c=getchar(); if(c==ch[0]||c==ch[1]||c==ch[2]||c==ch[3]||c==ch[5]||c=='\n')//要除去下個是‘(’的情況 也把以運算符歸到這里來 { printf("出錯2\n"); k=0; return 0;//加了開關(guān)變量和返回0的值使程序更以操作 } break; case'=': Pop(OPTR,x); c=getchar(); if(c==ch[0]||c==ch[1]||c==ch[2]||c==ch[3]||c==ch[5]||c=='\n')//把ch[6]的情況也忽略了但此時并沒有注意到右括號后面右運算符的情況 { printf("出錯2\n"); k=0; return 0; } break; case'': Pop(OPTR,theta); Pop(OPND,b); Pop(OPND,a);//注意這里是誰先出棧 Push(OPND,Operate(a,theta,b)); break; } } }//在這里判斷是否以運算符結(jié)束是不對的 return(Gettop(OPND)); } main() { int result; printf("輸入你的算術(shù)表達(dá)式:\n"); result=EvaluateExpression(); printf("結(jié)果是 :%d\n",result); return 0; } : 本計算器利用堆棧來實現(xiàn)。 1、定義后綴式計算器的堆棧結(jié)構(gòu) 因為需要存儲的單元不多,這里使用順序棧,即用一維數(shù)組來模擬堆棧: #define MAX 100 int stack[MAX]; int top=0; 因此程序中定義了長度為MAX的一維數(shù)組,這里MAX用宏定義為常數(shù)100,我們可以修改宏定義而重新定義堆棧的大小。 整型數(shù)據(jù)top為棧頂指示,由于程序開始時堆棧中并無任何數(shù)據(jù)元素,因此top被初始化為0。 2、存儲后綴式計算器的運算數(shù) 我們定義了堆棧stack[MAX]后,就可以利用入棧操作存儲先后輸入的兩個運算數(shù)。 下面看一下是如何實現(xiàn)的: int push(int i) /*存儲運算數(shù),入棧操作*/ { if(topMAX) { stack[++top]=i; /*堆棧仍有空間,棧頂指示上移一個位置*/ return 0; } else /*堆棧已滿,給出錯誤信息,返回出錯指示*/ { printf("The stack is full"); return ERR; } } 我們在調(diào)用函數(shù)push時,如果它的返回值為0,說明入棧操作成功;否則,若返回值為ERR(在程序中說明為-1),說明入棧操作失敗。 3、從堆棧中取出運算數(shù) 當(dāng)程序中讀完了四則運算符后,我們就可以從堆棧中取出已經(jīng)存入的兩個運算數(shù),構(gòu)成表達(dá)式,計算出結(jié)果。取出運算數(shù)的函數(shù)采用的正是出棧算法。在本例中,實現(xiàn)該算法的函數(shù) 為pop(): int pop(); /*取出運算數(shù),出棧操作*/ { int var; /*定義待返回的棧頂元素*/ if(top!=NULL) /*堆棧中仍有數(shù)據(jù)元素*/ { var=stack[top--]; /*堆棧指示下移一個位置*/ return var; } else /*堆棧為空,給出錯誤信息,并返回出錯返回值*/ printf("The stack is cmpty!\n"); return ERR; } 同樣,如果堆棧不為空,pop()函數(shù)返回堆棧頂端的數(shù)據(jù)元素,否則,給出??仗崾?,并返回錯誤返回值ERR。 4、設(shè)計完整的后綴式計算器 有了堆棧存儲運算數(shù),后綴式計算器的設(shè)計就很簡單了。程序首先提示用戶輸入第一個運算數(shù),調(diào)用push()函數(shù)存入堆棧中;而后提示用戶輸入第二個運算數(shù),同樣調(diào)用push()函數(shù)存入堆棧中。接下來,程序提示用戶輸入+,-,*,/四種運算符的一種,程序通過switch_case結(jié)構(gòu)判斷輸入運算符的種類,轉(zhuǎn)而執(zhí)行不同的處理代碼。以除法為例,說明程序的執(zhí)行流程: case '/': b=pop(); a=pop(); c=a/b; printf("\n\nThe result is %d\n",c); printf("\n"); break; 程序判斷用戶輸入的是除號后,就執(zhí)行上述代碼。首先接連兩次調(diào)用pop()函數(shù)從堆棧中讀出先前輸入的運算數(shù),存入整型數(shù)a和b中;然后執(zhí)行除法運算,結(jié)果存入單元c中。這時需要考慮究竟誰是被除數(shù),誰是除數(shù)。由于開始我們先將被除數(shù)入棧,根據(jù)堆?!跋冗M(jìn)后出”的原則,被除數(shù)應(yīng)該是第二次調(diào)用pop()函數(shù)得到的返回值。而除數(shù)則是第一次調(diào)用pop()函數(shù)得到的返回值。 最后程序打印出運算結(jié)果,并示提示用戶是否繼續(xù)運行程序: printf("\t Continue?(y/n):"); l=getche(); if(l=='n') exit(0); 如果用戶回答是"n",那么結(jié)束程序,否則繼續(xù)循環(huán)。 完整的程序代碼如下: #includestdio.h #includeconio.h #includestdlib.h #define ERR -1 #define MAX 100 /*定義堆棧的大小*/ int stack[MAX]; /*用一維數(shù)組定義堆棧*/ int top=0; /*定義堆棧指示*/ int push(int i) /*存儲運算數(shù),入棧操作*/ { if(topMAX) { stack[++top]=i; /*堆棧仍有空間,棧頂指示上移一個位置*/ return 0; } else { printf("The stack is full"); return ERR; } } int pop() /*取出運算數(shù),出棧操作*/ { int var; /*定義待返回的棧頂元素*/ if(top!=NULL) /*堆棧中仍有元素*/ { var=stack[top--]; /*堆棧指示下移一個位置*/ return var; /*返回棧頂元素*/ } else printf("The stack is empty!\n"); return ERR; } void main() { int m,n; char l; int a,b,c; int k; do{ printf("\tAriothmatic Operate simulator\n"); /*給出提示信息*/ printf("\n\tPlease input first number:"); /*輸入第一個運算數(shù)*/ scanf("%d",m); push(m); /*第一個運算數(shù)入棧*/ printf("\n\tPlease input second number:"); /*輸入第二個運算數(shù)*/ scanf("%d",n); push(n); /*第二個運算數(shù)入棧*/ printf("\n\tChoose operator(+/-/*//):"); l=getche(); /*輸入運算符*/ switch(l) /*判斷運算符,轉(zhuǎn)而執(zhí)行相應(yīng)代碼*/ { case '+': b=pop(); a=pop(); c=a+b; printf("\n\n\tThe result is %d\n",c); printf("\n"); break; case '-': b=pop(); a=pop(); c=a-b; printf("\n\n\tThe result is %d\n",c); printf("\n"); break; case '*': b=pop(); a=pop(); c=a*b; printf("\n\n\tThe result is %d\n",c); printf("\n"); break; case '/': b=pop(); a=pop(); c=a/b; printf("\n\n\tThe result is %d\n",c); printf("\n"); break; } printf("\tContinue?(y/n):"); /*提示用戶是否結(jié)束程序*/ l=getche(); if(l=='n') exit(0); }while(1); } : #include stdio.h #include conio.h #include malloc.h #include stdlib.h #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 typedef int Status; #define STACK_INIT_SIZE 100 //初始分配量 #define STACKINCREMENT 10 //存儲空間的分配增量 typedef char ElemType; typedef ElemType OperandType; //操作數(shù) typedef char OperatorType; typedef struct { ElemType *base; ElemType *top; int stacksize; }SqStack; Status InitStack(SqStack S) { //構(gòu)造一個空棧S S.base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType)); if(!S.base) exit (OVERFLOW); S.top = S.base; S.stacksize = STACK_INIT_SIZE; return OK; } Status GetTop(SqStack S){ ElemType e; if (S.top == S.base) return ERROR; e = *(S.top-1); return e; } Status Push (SqStack S,ElemType e) { //插入元素e為新的棧頂元素 if (S.top - S.base = S.stacksize){ S.base = (ElemType *) realloc ( S.base, (S.stacksize + STACKINCREMENT) * sizeof(ElemType)); if(!S.base) exit (OVERFLOW); S.top = S.base + S.stacksize; S.stacksize += STACKINCREMENT; } *S.top++ = e; return OK; } Status Pop (SqStack S,ElemType e){ //若棧不空,則刪除S的棧頂元素,用e返回其值,并返回OK;否則返回ERROR if(S.top == S.base) return ERROR; e = * --S.top; return OK; } char In(char c,char OP[]) { if(c=35 c=47) return 1; else return 0; } char OP[8]=; int m[7][7]={1,1,2,2,2,1,1, 1,1,2,2,2,1,1, 1,1,1,1,2,1,1, 1,1,1,1,2,1,1, 2,2,2,2,2,0,-1, 1,1,1,1,-1,1,1, 2,2,2,2,2,-1,0};//1 2 0 = -1 不存在 char Precede(char i,char j) { int a,b; char *p; for(p=OP,a=0;*p!='\0';p++,a++) if(*p==i) break; for(p=OP,b=0;*p!='\0';p++,b++) if(*p==j) break; if(m[a][b]==1) return ''; else if(m[a][b]==2) return ''; else if(m[a][b]==0) return '='; else return 'O'; } char Operate(char a,char theta,char b) { if(a47) a=atoi(a); if(b47) b=atoi(b); switch(theta) { case '+': return a+b; break; case '-': return a-b; break; case '*': return a*b; break; case '/': return a/b; break; } } OperandType EvaluateExpression() { SqStack OPTR,OPND; OperandType a,b,c; OperatorType theta; InitStack(OPTR); Push(OPTR,'#'); InitStack(OPND); c=getchar(); while (c!='#' || GetTop(OPTR)!='#') { if (!In(c,OP)) else switch(Precede(GetTop(OPTR),c)) { case '' : Push(OPTR,c); c = getchar(); break; case '=' : Pop(OPTR,c); c = getchar(); break; case '' : Pop(OPTR,theta); Pop(OPND,b); Pop(OPND,a); Push(OPND,Operate(a,theta,b)); break; } } return GetTop(OPND); } void main() { printf("(以#為結(jié)束符)\n"); printf("請輸入:\n"); int a; a=(int)EvaluateExpression(); printf("%d",a); getch(); } : ls都正確 : C++ In Action這本書里面有表達(dá)式求值的詳細(xì)項目分析. : 數(shù)據(jù)結(jié)構(gòu)的書里面都有的,仔細(xì)看一下 : studyall123的只能對0到9的數(shù)字運算才有效,對于10以上的數(shù)字就不行!不知道有沒有更好的方法! : 現(xiàn)在的人,連google一下都懶啊 : 實際上是按照逆波蘭式的順序讓輸入的表達(dá)式入棧,再根據(jù)運算符優(yōu)先級來計算。 : lenrning!
不用困擾啊,你試著做就很輕松解決了。關(guān)鍵是選對方法。
辦法有不少于2種。 比較正式的做法是
先用遞歸把函數(shù)參數(shù)解析出來
當(dāng)解析到最后一層時,把上一層的函數(shù)保留下來,最后只保留最后一層的函數(shù)名和最后一層的參數(shù)名。放在堆棧里。
將結(jié)果把按順序打印出來
我想困擾你的應(yīng)該是你對遞歸算法,或者是堆棧的原理不太熟悉。另外就是對python的數(shù)組這個數(shù)據(jù)結(jié)構(gòu)的push,pop方法不熟悉。
你分別單獨練習(xí),練熟了,再做這道題就很輕松了。
還有一種偏門的方法,直接統(tǒng)計括號數(shù),然后計算括號層數(shù)。倒數(shù)一層,找到匹配的括號對,把括號對里的函數(shù)提出來,再用,進(jìn)行split,最后再用join接起來。這樣代碼量,估計3-4行就解決問題了。也不需要遞歸與堆棧。不過,這樣一來,你的老師要失望了。他的目標(biāo)應(yīng)該是讓你練習(xí)遞歸的。
在一個 最小堆 (min heap) 中,如果 P 是 C 的一個父級節(jié)點,那么 P 的 key(或 value) 應(yīng)小于或等于 C 的對應(yīng)值。 正因為此,堆頂元素一定是最小的,我們會利用這個特點求最小值或者第 k 小的值。
在一個 最大堆 (max heap) 中,P 的 key(或 value) 大于或等于 C 的對應(yīng)值。
以python為例,說明堆的幾個常見操作,這里需要用到一個內(nèi)置的包:heapq
python中使用堆是通過傳入一個數(shù)組,然后調(diào)用一個函數(shù),在原地讓傳入的數(shù)據(jù)具備堆的特性
需要注意的是,heapify默認(rèn)構(gòu)造的是小頂堆(min heap),如果要構(gòu)造大頂堆,思路是把所有的數(shù)值倒轉(zhuǎn),既* -1,例如:
使用heapq提供的函數(shù): heappop 來實現(xiàn)
具體使用方式參考 初始化Heapify
使用heapq提供的函數(shù): heappush 來實現(xiàn)
同時heapq還提供另外一個函數(shù): heappushpop ,能夠在一個函數(shù)實現(xiàn)pushpop兩個操作;順序是:先push再pop
根據(jù)官方文檔的描述,這個函數(shù)會比先在外圍先調(diào)用heappush,再調(diào)用heappop,效率更高
先pop數(shù)據(jù)再push數(shù)據(jù),和heappushpop的順序是反著的; 同樣的,這樣調(diào)用的性能也會比先調(diào)用heappop再調(diào)用heappush更好
如果pop的時候隊列是空的,會拋出一個異常
可以通過 heapq.merge 將多個 已排序 的輸入合并為一個已排序的輸出,這個本質(zhì)上不是堆;其實就是用兩個指針迭代
對于這個問題,有一個算法題可以實現(xiàn)相同的功能
從 iterable 所定義的數(shù)據(jù)集中返回前 n 個最大/小元素組成的列表。
函數(shù)為: heapq.nlargest() | heapq.nsmallest()
heapq - Heap queue algorithm - Python 3.10.4 documentation
新聞標(biāo)題:push函數(shù)python push函數(shù)代碼
本文網(wǎng)址:http://jinyejixie.com/article10/hpcpdo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供手機(jī)網(wǎng)站建設(shè)、電子商務(wù)、網(wǎng)站營銷、營銷型網(wǎng)站建設(shè)、微信小程序、云服務(wù)器
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)