數組Q[n]用來表示一個循環隊列,f為當前隊列頭元素的前一個位置r為隊尾元素的位置 假定隊列元素的個數小於n,計算隊列中元素個數的公式?
解答:對於非循環隊列來說,尾指針和頭指針的差值便是隊列的長度,而對於循環隊列,差值可能是負值 所以需要將差值加上MAXSIZE(本題是n),然后與MAXSIZE(本題是N)求余,即是(r-f+n)%n
(1)將編號為0和1的兩個棧存放於一個數組空間V[m]中,棧底分別處於數組的兩端 當第0號棧的棧頂指針top[0]等於-1時該棧為空;當第一號棧的棧頂指針top[1]等於m時,該棧為空。兩個棧均從兩端向中間增長 試編寫雙棧初始化,判斷棧空,棧滿,進棧,出棧等等算法的函數 雙棧數據結構的定義如下所示
`////-----棧的數據結構定義-----
typedef struct
{
int top[2],bot[2]; ///棧頂和棧底指針
SElemtype *v; //棧數組
int m; //棧最大可容納元素個數
}DblStack;`
`///-----雙棧的初始化-----
int init()
{ S.top[0]=-1; ///第0號棧為空
S.top[1]=m; ///第一號棧為空
return 1; ///初始化成功
} `
`////------判斷棧空-------
int Empty()
{ return(S.top[0]==-1&&S.top[1]==m); }`
`////-----入棧操作-----
int push(Stack &s,int i,int x)////i為棧號,i=0表示左棧,i=1表示右棧,x是入棧元素 ,入棧成功返回1,失敗返回0;
{ if(i<0||i>1)
{ count<<"棧號輸入不對"<<endl;
exit(0);
}
if(S.top[1]-S.top[0]==1)
{count<<"棧已經滿"<<endl; return(0); }
switch(i)
{ case 0: S.v[++S.top[0]]=x; return(1); ///第零號棧入棧操作
break;
case 1:S.V[--S.top[1]]=x; } ///第一號棧入棧操作
} `
`////------出棧操作----------
ElemType pop (Stack &s,int i) ///退棧,i代表棧號 i=0表示左棧
{ if(i<0||i>1)
{ count<<"棧號輸入不對"<<endl;
exit(0); }
Switch(i)
{case 0: if(S.top[0]==-1) ////判斷棧是否為空能否出棧
{count<<"棧空"<<endl;return(-1); }
else
return(S.V[S.top[0]--]);
case 1: if(S.top[1]==m)
{count<<"棧空"<<endl;return(-1); }
else
return (S.V[S.top[1]++]); }
}`
回文是指正讀反讀均相同的字符序列,如“abba"和"abdba"均是回文 但是"good"不是回文試寫一個算法判斷給定的字符序列是否為回文(提示:將一半字符入棧)
`////-----回文判斷------
#define StackSize 100 //假定預分配的棧空間最多為100個元素
typedef char DataType; //假定棧元素的數據類型為字符
typedef Struct
{DataType data[StackSize];
int top;
}SeqStack; ///棧數據結構的定義
int IsHuiwen (char *t)
{ //判斷t字符向量是否為回文,若是返回1,不是返回0
SeqStack S;
int i,length;
char temp; ///temp存儲暫時變量
initStack(&S);
length=strlength(t); ///求向量長度
for(i=0;i<length/2;i++)
push(&S,t[i]); ///將一半的字符入棧
while(!EmptyStack(&S))
{ ///每彈出一個字符與相應字符比較
temp=Pop(&S);
if(temp!=S[i])
return 0; ///不等則返回0;
else
i++;}
return 1; ///比較完畢若相等則返回1
}`
假設以帶頭結點的循環鏈表表示隊列,並且只設一個指針指向隊尾元素結點(不設頭指針)以此編寫相應的置空隊列,判斷隊列是否為空 入隊和出隊等算法。
`////------預定義鏈隊的結構------
typedef struct queuenode
{ Datatype data;
struct queuenode *next;
} QueueNode; //結點類型的定義
typedef struct
{ queueNode *rear; ///只設一個指向隊尾元素的指針
}Linkqueue;`
`///-----置空隊--------
void initQueue(LinkQueue *Q)
{ ///置空隊就是讓頭結點成為隊尾元素
QueueNode *s;
Q.rear=Q.rear->next; //將隊尾指針指向頭結點
while(Q.rear!=Q.rear->next) ///當隊列非空將隊中元素逐個出隊
{ S=Q.rear->next; ///S指向隊尾元素
Q.rear->next=S->next; //修改尾結點的指針域
delete S; } //回收結點空間
}`
`///----判隊空-------
int EmptyQueue (LinkQueue &Q)
{ //判斷隊空 當頭結點的next指針 指向自己時為空隊
return Q.rear->next->next==Q.rear->next; }`
`///----入隊操作-----
void EnQueue (LinkQueue &Q , Datatype x)
{ //入隊,也就是尾結點處插入元素
QueueNode *p=new QueueNode; //申請新結點
p->data=x;
p->next=Q.rear->next; ///初始化新結點並鏈入
Q.rear->next=p;
Q.rear=p; //將尾指針移至新結點
}`
`////-------出隊操作--------
Datatype DeQueue (LinkQueue *Q)
{ //出隊,把頭結點之后的元素摘下
Datatype t;
QueueNode *p; //定義下頭結點
if(EmptyQueue(Q))
Error("Queue underflow");
p=Q.rear->next->next;//p指向將要摘下的結點
x=p->data; //保存結點中的數據
if(p==Q.rear)
{ //當隊列中只有一個結點時,P結點出隊后,要將隊尾指針指向頭結點
Q.rear=Q.rear->next;
Q.rear->next=p->next; }
else
Q.rear->next->next=p-next; //摘下結點p
delete p; //釋放被刪除結點
return x; }`
已知f為單鏈表的表頭指針,鏈表中存儲的都是整型數據,試寫出實現下列運算的遞歸算法
-
求鏈表的最大整數
-
求鏈表的結點個數
-
求所有整數的平均值
`///------求鏈表中的最大整數-------- int GetMax(Linklist p) { if(!p->next) return p->data; else { int max=GetMax(p->next); return p->data>=max? p->data:max; } } ` `///-----求鏈表的結點個數------- int Getlength(Linklist p) { if(!p->next) return 1; else { return Getlength(p->next) +1; } }` `///-----求所有整數的平均值------- double GetAverage(Linklist p,int n) { if(!p->next) return p->data; else { double ave=GetAverage(p-next,n-1); return (ave *(n-1)+p->data)/n; } }`