c语言 栈结构存放数据类型,数据结构——栈的详解
棧和隊列是兩種重要的線性結構,從數據結構的角度看,棧和隊列也是線性表,其特殊性在于棧和隊列的基本操作是線性表的子集。他們是操作受限的線性表,因此,可稱為限定性的數據結構。但從數據類型角度看,他們是和線性表大不相同的兩類重要的的抽象數據類型。
文章目錄
C語言中的棧
棧的定義
C語言中棧的基本操作
棧的初始化
判斷是否為空棧
判斷是否為滿棧
入棧
出棧
C語言實現棧的具體代碼
C++中的棧
C++中棧的基本操作
初始化
判斷是否為空棧
入棧
出棧
返回棧頂元素
返回棧中元素數目
C語言中的棧
棧的定義
棧(stack)是限定僅在表尾進行插入或者刪除的線性表。對于棧來說,表尾端稱為棧頂(top),表頭端稱為棧低(bottom)。不含元素的空表稱為空棧。因為棧限定在表尾進行插入或者刪除,所以棧又被稱為后進先出的線性表(簡稱LIFO:Last in, First out.結構)。
C語言中棧的基本操作
棧的基本操作主要有:棧的初始化、判空、判滿、取棧頂元素、在棧頂進行插入和刪除。在棧頂插入元素稱為入棧,在棧頂刪除元素稱為出棧。
棧的初始化
棧和線性表類似,也有兩種存儲表示方法順序棧和鏈棧,鏈棧的操作是線性表操作的特例,操作比較容易實現。順序棧即棧的順序存儲結構是利用一組地址連續的存儲單元依次存放自棧底到棧頂的數據元素,同時附設指針top指示棧頂元素在順序棧中的位置,top = 0表示空棧。由于棧在使用的過程中所需要的大小難以估計,所以通常是先為棧分配一個基本容量,然后再使用的過程中,當棧的空間不夠使用的時候再繼續追加存儲空間。我們以下述類型說明作為順序棧的定義:
typedef struct{
SDataType *base; //棧底指針
SDataType *top; //棧頂指針
int StackSize; //當前已經分配的存儲空間,以元素為單位
}SqStack;
棧的初始化操作為:按照設定的初始分配量進行第一次存儲分配,這里使用==malloc()==函數來分配存儲空間。malloc()函數的詳細說明請看:malloc詳細說明。base作為棧底指針,它始終指向棧底,所以s.top = s.base可以作為??盏臉擞洝op為棧頂指針,top的初值指向棧底。每當插入一個元素時top加1,彈出一個元素時top減1,因此,非空棧中的棧頂指針始終在棧頂元素的下一個位置上。
//初始化順序棧,構造一個空棧
Status InitStack(SqStack &S){
//分配存儲空間
S.base = (SDataType *)malloc(STACK_INIT_SIZE*sizeof(SDataType));
if(!S.base){
//如果分配失敗,則返回error
return OVERFLOW;
}
//S.top 始終指向棧頂元素的下一個位置
S.top = S.base; //初始狀態下為空棧
S.StackSize = STACK_INIT_SIZE; //當前已經分配的存儲容量為100個
return OK;
}
判斷是否為空棧
當我們彈出棧頂元素時,往往需要判斷一下棧是否為空來防止發生下溢。上面我們說到==base作為棧底指針,它始終指向棧底,所以s.top = s.base可以作為??盏臉擞?。==所以我們可以這樣判斷棧是否為空:
//判斷是否為空棧
void judgeNull(SqStack &s){
if(s.top == s.base){
printf("此棧為空棧!\n");
}else{
printf("此棧不為空棧!\n");
}
}
判斷是否為滿棧
當我們使一個元素入棧的之前,我們往往需要判斷一下棧是否為滿棧,防止發生上溢的情況。因為我們定義了一個StackSize來表示當前已經分配的存儲空間,所以我們可以用s.top - s.base 來算出當前已經使用的??臻g。所以當s.top - s.base == s.StackSize時表示已經滿棧:
//判斷是否為滿棧
void judgeFull(SqStack &s){
if(s.top-s.base == s.StackSize){
printf("棧滿!\n");
}else{
printf("棧未滿!\n");
}
}
入棧
入棧時我們首先要判斷棧是否為滿棧,如果為滿棧我們要首先追加存儲空間,然后才能將元素入棧。realloc()函數詳解請看realloc詳解
//入棧
Status Push(SqStack &s,SDataType e){
SDataType *p;
//首先判斷棧是不是滿的(上溢)
if(s.top-s.base == s.StackSize){
//追加空間
p = (SDataType *)realloc(s.base,(STACK_INIT_SIZE+STACKINCREMENT)*sizeof(SDataType));
if(!p){
//如果沒有找到符合條件的存儲空間,則返回error
return OVERFLOW;
}
//成功找到則使s.base指向p
s.base = p;
s.top = s.base + s.StackSize;
s.StackSize += STACKINCREMENT;
}
//先插入元素,然后將棧頂指針加 1
*(s.top) = e;
s.top++;
return OK;
}
出棧
出棧時我們首先要判斷棧是否為空棧。如果棧已經空了,則返回error。
//出棧
Status Pop(SqStack &s,SDataType &e){
//判斷是否會發生下溢
if(s.top != s.base){
s.top--; //先將棧頂指針減 1
e = *(s.top);
}else{
return 0;
}
return e;
}
C語言實現棧的具體代碼
#include
#include
#define STACK_INIT_SIZE 100//棧的初始容量
#define STACKINCREMENT 10//容量增量
#define OK 1
#define OVERFLOW -2
typedef int SDataType;
typedef int Status;
typedef struct{
SDataType *base; //棧底指針
SDataType *top; //棧頂指針
int StackSize; //當前已經分配的存儲空間,以元素為單位
}SqStack;
//初始化順序棧,構造一個空棧
Status InitStack(SqStack &S){
//分配存儲空間
S.base = (SDataType *)malloc(STACK_INIT_SIZE*sizeof(SDataType));
if(!S.base){
//如果分配失敗,則返回error
return OVERFLOW;
}
//S.top 始終指向棧頂元素的下一個位置
S.top = S.base; //初始狀態下為空棧
S.StackSize = STACK_INIT_SIZE; //當前已經分配的存儲容量為100個
return OK;
}
//入棧
Status Push(SqStack &s,SDataType e){
SDataType *p;
//首先判斷棧是不是滿的(上溢)
if(s.top-s.base == s.StackSize){
//追加空間
p = (SDataType *)realloc(s.base,(STACK_INIT_SIZE+STACKINCREMENT)*sizeof(SDataType));
if(!p){
//如果沒有找到符合條件的存儲空間,則返回error
return OVERFLOW;
}
//成功找到則使s.base指向p
s.base = p; //系統會將原來的內容復制過來
s.top = s.base + s.StackSize;
s.StackSize += STACKINCREMENT;
}
//先插入元素,然后使棧頂指針加 1
*(s.top) = e;
s.top++;
return OK;
}
//出棧
Status Pop(SqStack &s,SDataType &e){
//判斷是否會發生下溢
if(s.top != s.base){
s.top--; //先將棧頂指針減 1
e = *(s.top);
}else{
return 0;
}
return e;
}
//判斷是否為空棧
void judgeNull(SqStack &s){
if(s.top == s.base){
printf("此棧為空棧!\n");
}else{
printf("此棧不為空棧!\n");
}
}
//判斷是否為滿棧
void judgeFull(SqStack &s){
if(s.top-s.base == s.StackSize){
printf("棧滿!\n");
}else{
printf("棧未滿!\n");
}
}
int main(){
SqStack s;
SDataType element;
InitStack(s); //初始化棧
//將1-5入棧
for(int i=1;i<=10;i++){
Push(s,i);
}
judgeNull(s);
judgeFull(s);
printf("出棧:\n");
//只要棧不為空
while(s.top != s.base){
Pop(s,element); //出棧的元素用e接收
printf("%d ",element);
}
printf("\n");
judgeNull(s);
return 0;
}
C++中的棧
C++ 對模板(Template)支持得很好,STL 就是借助模板把常用的數據結構及其算法都實現了一遍,并且做到了數據結構和算法的分離。STL的代碼從廣義上講分為三類:algorithm(算法)、container(容器)和iterator(迭代器),幾乎所有的代碼都采用了模板類和模版函數的方式,這相比于傳統的由函數和類組成的庫來說提供了更好的代碼重用機會。在C++標準中,STL被組織為下面的13個頭文件:、、、、、、、、、、、和。其中的就是棧。
C++的STL已經將棧的操作都封裝成了函數,我們只需要引進#include頭文件即可使用。
C++中棧的基本操作
初始化
我們可以直接使用stacks;來創建一個空的 stack 對象。
判斷是否為空棧
使用empty()函數來判斷棧是否為空。
入棧
使用push()函數來完成入棧操作。
出棧
使用pop()函數實現出棧
返回棧頂元素
使用top()函數返回棧頂元素
返回棧中元素數目
使用size()函數返回棧中元素的數目。
以上就是C語言和C++中棧的基本用法了,如果你覺得我的文章對你有用請點個贊支持一下吧,如果喜歡我寫的文章那么請點個關注再走。
下一篇將繼續寫數據結構的隊列,后續將會再寫一些有關棧和隊列的具體應用。我是ACfun:一個成長中的程序猿,感謝大家的支持。
總結
以上是生活随笔為你收集整理的c语言 栈结构存放数据类型,数据结构——栈的详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 蜜蜂实训平台c语言考试答案,北理c语言上
- 下一篇: c语言知道算法写不出代码,这个代码怎么写