C++中棧構造樹立與操作具體解析。本站提示廣大學習愛好者:(C++中棧構造樹立與操作具體解析)文章只能為提供參考,不一定能成為您想要的結果。以下是C++中棧構造樹立與操作具體解析正文
甚麼是棧構造
棧構造是從數據的運算來分類的,也就是說棧構造具有特別的運算規矩,即:落後先出。
我們可以把棧懂得成一個年夜倉庫,放在倉庫門口(棧頂)的貨色會優先被掏出,然後再掏出外面的貨色。
而從數據的邏輯構造來看,棧構造肇端就是一種線性構造。
假如從數據的存儲構造來進一步劃分,棧構造包含兩類:
次序棧構造:
即便用一組地址持續的內存單位順次保留棧中的數據。在法式中,可以界說一個指定年夜小的構造數組來作為棧,序號為0的元素就是棧低,再界說一個變量top保留棧頂的序號便可。
鏈式棧構造:
即便用鏈表的的情勢保留棧中各元素的值。鏈表首部(head指針所指向元素)為棧頂,鏈表尾部(指向地址為NULL)為棧底。
在棧構造中只能在一端停止操作,該操作端稱為棧頂,另外一端稱為棧底。也就是說,保留和掏出的數據都只能從棧構造的一端停止。從數據的運算角度來剖析,棧構造是依照“落後先出”的准繩處置結點數據的。
在棧構造中,只要棧頂元素是可以拜訪的,棧構造的數據運算也長短常簡略。普通棧構造的根本操作只要兩個:
入棧(Push):將數據保留到棧頂的操作。停止入棧操作前,先修正棧頂指針,使其向上移一個元素地位,然後將數據保留到棧頂指針所指的地位。
出棧(Pop):將棧頂數據彈出的操作。經由過程修正棧頂指針,使其指向棧中的下一個元素。
接上去,我們應用C++說話樹立次序棧,並完成次序棧構造的根本運算
預備數據
預備在棧操作中須要用到的變量及數據構造等。
#define MAXLEN 50
struct DATA
{
string name;
int age;
};
struct StackType
{
DATA data[MAXLEN+1];
int top;
};
界說棧構造的長度MAXLEN,棧構造的數據元素類型DATA,和棧構造的數據構造StackType。在數據構造StackType中,data為數據元素,top為棧頂的序號。當top=0時,表現棧為空,當top=MAXLEN時表現棧滿。
數組元素都是充下標0開端的,這裡為了講述和懂得便利,我們從下標1開端記載數據結點,下標0的地位不消。
初始化棧構造
在應用棧構造之前,起首須要創立一個空的次序棧,也就是初始化次序棧。次序棧的初始化操作以下:
(1)依照符號常量MAXLEN指定年夜小請求一片內存空間,用來保留棧中的數據
(2)設置棧頂指針的值為0,表現一個空棧。
示例代碼以下:
StackType *STInit()
{
StackType *p;
if(p=new StackType) //請求棧空間
{
p->top=0; //設置棧頂為0
return p; //前往棧頂指針
}
return NULL;
}
起首用new請求內存,然後設置棧頂為0,然後前往請求內存的首地址,請求掉敗前往NULL;
斷定空棧
斷定棧構造能否為空,假如是空棧,則表現該棧構造中沒稀有據,此時可以停止入棧操作,然則弗成以停止出棧操作。
示例代碼以下:
int STIsEmpty(StackType *s)
{
int t;
t=(s->top==0); //經由過程棧頂的值停止斷定
return t;
}
輸出參數s為一個指向操作的棧的指針。依據棧頂指針top斷定能否為0,斷定棧能否為空。
斷定滿棧
斷定棧構造能否為滿。假如是滿棧,則表現該棧構造中沒有過剩的空間來保留額定數據。此時弗成以停止入棧操作,然則可以停止進棧操作。
示例代碼以下:
int STIsFull(StackType *s)
{
int t;
t=(s->top==MAXLEN);
return t;
}
輸出參數s為一個指向操作的棧的指針。依據棧頂指針top斷定能否和MAXLEN相等,斷定棧能否已滿。
清空棧
清空棧就是棧中一切的數據被消除。 示例代碼以下:
void STClear(StackType *s)
{
s->top=0;
}
將棧頂指針top設置為0,表現履行清空棧操作。(這裡只是邏輯大將棧中數據清空,現實上只是將top設置為0,今後再添加數據會籠罩本來的數據)
釋放空間
釋放空間是釋放棧構造所占用的內存單位,應用delete釋放用new運算符請求的內存空間。
示例代碼以下:
void STFree(StackType *s)
{
delete s;
}
在法式中直接挪用delete運算符釋放已分派的內存空間。普通在不須要應用棧構造時挪用該函數,特殊是在法式停止的時刻。
入棧
入棧(Push)是棧構造的根本操作,重要操作是將數據元素保留到棧構造。入棧操作的詳細步調以下:
(1)起首斷定棧頂top,假如top年夜於等於MAXLEN,則表現溢出,停止失足處置。不然履行以下操作。
(2)設置top=top+1(棧頂指針加1,指向入棧地址)
(3)將入棧呀U尿素保留到top指向的地位。
示例代碼以下:
int PushST(StackType *s,DATA data)
{
if((s->top+1)>MAXLEN)
{
cout<<"棧溢出"<<endl;
return 0;
}
s->data[++s->top]=data; //將元素壓入棧
return 1;
}
輸出參數s為一個指向操作的棧的指針,輸出參數data是須要入棧的數據元素。法式起首斷定棧能否溢出,假如溢出就給出正告,不停止入棧操作,不然修正棧頂指針,即top先加1,然後將data放到top如今指向的數據單位。
出棧
出棧(Pop)是占領诶狗的根本操作,重要操作與入棧相反,它是從棧頂彈出一個數據元素,出棧操作的詳細步調以下:
(1)起首斷定棧頂top,假如top等於0,則表現為驚恐在哪,停止失足處置。不然履行上面的操作。
(2)將棧頂指針top所指向的地位的元素前往(現實是前往的指針)
(3)將top的減1,指向棧的下一個元素,本來棧頂的元素被彈出。
DATA * PopST(StackType *s)
{
if(s->top==0)
{
cout<<"棧為空,不克不及再輸入!"<<endl;
exit(0);
}
return &(s->data[s->top--]);
}
當棧中稀有據時,該函數前往值是一個指向DATA類型數據的指針。
讀取點構造
讀取點構造也就是讀取棧構造中結點的數據。因為棧構造只能在一端停止操作,是以這裡的讀操作其實就是讀站點的數據。
須要留意的是,讀節點數據的操作和出棧操作分歧。讀結點操作僅僅是顯示棧頂結點數據的內容,而出棧操作則將棧頂數據彈出。
示例代碼以下:
DATA *PeekST(StackType *s)
{
if(s->top==0)
{
cout<<"棧已空"<<endl;
exit(0);
}
return &(s->data[s->top]);
}
比較出棧的示例代碼,不難發明讀取點構造異樣前往了棧頂結點的地址,然則卻沒有使top減1.
完全示例
上面是棧的根本操作的完全示例:
法式代碼:
#include<iostream>
#include<string>
using namespace std;
#define MAXLEN 50
struct DATA
{
string name;
int age;
};
struct StackType
{
DATA data[MAXLEN+1];
int top;
};
/******************初始化棧構造****************/
StackType *STInit()
{
StackType *p;
if(p=new StackType) //請求棧空間
{
p->top=0; //設置棧頂為0
return p; //前往棧頂指針
}
return NULL;
}
/****************斷定空棧**********************/
int STIsEmpty(StackType *s)
{
int t;
t=(s->top==0); //經由過程棧頂的值停止斷定
return t;
}
/**********************斷定滿棧****************/
int STIsFull(StackType *s)
{
int t;
t=(s->top==MAXLEN);
return t;
}
/**********************清空棧**********************/
void STClear(StackType *s)
{
s->top=0;
}
/********************釋放空間********************/
void STFree(StackType *s)
{
delete s;
}
/**********************入棧***********************/
int PushST(StackType *s,DATA data)
{
if((s->top+1)>MAXLEN)
{
cout<<"棧溢出"<<endl;
return 0;
}
s->data[++s->top]=data; //將元素壓入棧
return 1;
}
/************************出棧***********************/
DATA * PopST(StackType *s)
{
if(s->top==0)
{
cout<<"棧為空,不克不及再輸入!"<<endl;
exit(0);
}
return &(s->data[s->top--]);
}
/**********************讀取點構造*******************/
DATA *PeekST(StackType *s)
{
if(s->top==0)
{
cout<<"棧已空"<<endl;
exit(0);
}
return &(s->data[s->top]);
}
/*****************進入主函數**********************/
int main()
{
StackType *stack;
DATA data,*p_data;
stack=STInit();
cout<<"===============入棧操作:============="<<endl;
cout<<"輸出姓名 ,年紀停止入棧操作:"<<endl;
//履行入棧操作
while(1)
{
cin>>data.name>>data.age;
if(data.name=="0")
{
break; //當姓名和年紀都是0的時刻加入輸出
}else
{
PushST(stack,data);
}
}
p_data=PopST(stack);
cout<<"彈出棧頂元素"<<endl;
cout<<"name:"<<p_data->name<<",age:"<<p_data->age<<endl;
p_data=PeekST(stack);
cout<<"輸入棧頂元素"<<endl;
cout<<"name:"<<p_data->name<<",age:"<<p_data->age<<endl;
cout<<"================將一切的的數據出棧:============="<<endl;
while(1)
{
p_data=PopST(stack);
cout<<"name:"<<p_data->name<<",age:"<<p_data->age<<endl;
}
STFree(stack);
return 0;
}
法式運轉界面: