棧的線性儲存結構與鏈式儲存結構的實現(C語言)。

順序棧,即棧的儲存結構是利用地址連續的一組儲存單元依次存放棧頂到棧底的數據元素.node

棧的結構:代碼以下函數

#include<stdio.h>
#include<stdlib.h>
#define STACK_INIT_SIZE 100/*儲存空間初始分配量*/
#define STACKINCREMENT 10/*儲存空間分配增量*/
typedef int ElemType;
typedef int Status;
/*-----------------棧的順序儲存表示--------------------------*/
typedef struct {
 ElemType *base;/*在棧構造以前和銷燬以後base的值爲NULL*/
 ElemType *top; /*棧頂指針*/
 int stacksize; /*當前以分配的空間,以元素爲單位*/
}SqStack;

構造一個空棧,先爲棧分配初始大小,base指向分配空間,並令base==top。用stacksize來儲存目前已經分配的空間,以元素的個數爲單位。代碼以下:學習

 Status InitStack(SqStack *S){/*構造一個空棧*/
 S->base=(ElemType *)malloc(STACK_INIT_SIZE*sizeof(ElemType));
 if(!S->base)exit(0);//儲存分配失敗
 S->top=S->base;
 S->stacksize=STACK_INIT_SIZE;
 return 1;
}

取出元素,即爲出棧,首先檢測棧是否爲空,若是不是取出棧頂元素,棧頂指針向前移位。即向靠近棧底的一方移位。代碼以下:測試

Status GetTop(SqStack *S,ElemType *e)
{/*若是棧不爲空,返回棧頂元素*/
 if(S->base==S->top)return 0;
 else
 {
  S->top--;
  *e=*(S->top+1);
  return 1;
 }
}

存入元素即爲壓棧。首先檢測是否有儲存空間:若是沒有則分配。代碼以下:spa

 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(0);
  S->top=S->base+S->stacksize; 
  S->stacksize+=STACKINCREMENT;
 }
 S->top++;
 *S->top=*e;
 return 1;
}

ealloc,malloc,calloc的區別指針

三個函數的申明分別是:
void* realloc(void* ptr, unsigned newsize);
void* malloc(unsigned size);
void* calloc(size_t numElements, size_t sizeOfElement);
都在stdlib.h函數庫內
它們的返回值都是請求系統分配的地址,若是請求失敗就返回NULLcode

malloc用於申請一段新的地址,參數size爲須要內存空間的長度,如:
char* p;
p=(char*)malloc(20);內存

calloc與malloc類似,參數sizeOfElement爲申請地址的單位元素長度,numElements爲元素個數,如:
char* p;
p=(char*)calloc(20,sizeof(char));it

測試函數:io

void main()
{
 int z,i;
 SqStack S;
 InitStack(&S);/*初始化棧*/
 printf("壓棧,存入數據1,2,3,4,5:\n");
 for(i=1;i<=5;i++)
 {
  Push(&S,&i);
 }
 printf("出棧,取出前兩個:");
 for(i=1;i<=2;i++)
 {
  GetTop(&S,&z);
  printf("%d\t",z);
 }
 printf("\n");
 printf("壓棧,存入數據11,12,13:\n");
 for(i=11;i<=13;i++)
 {
  Push(&S,&i);
 }
  printf("出棧,取出前四個:\n");
 for(i=1;i<=4;i++)
 {
  GetTop(&S,&z);
  printf("%d\t",z);
 }
  system("pause");
}

運行結果以下:

-----------------------------------------------------------------------------------------------------------------------------

棧的鏈式儲存結構:

#include<stdio.h>
#include<stdlib.h>
typedef int Elemtype;
typedef int Status;
typedef struct Snode
{
 Elemtype data;  /*數據域*/
 struct Snode *next; /*指針域*/
}Snode,*LinkStack;

假設S是linkStack型的變量,s爲鏈棧的頭指針,而且始終指向鏈頂,即線性表的第一個元素。壓棧入棧等操做代碼以下:

 void Init_StackL(LinkStack *S)
{
 *S=NULL;
}
Status Push_L(LinkStack *S,Elemtype x)   /*將元素x插入到棧頂位置*/
{
 LinkStack p;
 p=(LinkStack)malloc(sizeof(Snode));  /*新節點生成*/
 p->data=x;         /*向新節點賦值*/
 p->next=*S;         /*向棧頂插入新結點*/
 *S=p;
 return 1;
}
Status  Pop_L(LinkStack *S,Elemtype *temp_) /*刪除鏈棧的頂元素*/
{
 LinkStack p;
 Elemtype temp;
 if(*S==NULL) return 0;      /*對於空棧則退出*/
 temp=(*S)->data;       /*暫存棧頂元素值,以便返回*/
 p=*S;           /*使棧頂指向下一結點*/
 *S=p->next;
 free(p);          /*釋放棧頂元素*/
 *temp_=temp;
 return 1;
}

測試函數以下,與線性棧的測試數據相同,代碼以下:

 void main()
{
 int i,z;
 LinkStack S;
 Init_StackL(&S);
 printf("壓棧,存入數據1,2,3,4,5:\n");
 for(i=1;i<=5;i++)
 {
  Push_L(&S,i);
 }
 printf("出棧,取出前兩個:");
 for(i=1;i<=2;i++)
 {
  Pop_L(&S,&z);
  printf("%d\t",z);
 }
 printf("\n");
 printf("壓棧,存入數據11,12,13:\n");
 for(i=11;i<=13;i++)
 {
  Push_L(&S,i);
 }
  printf("出棧,取出前四個:\n");
 for(i=1;i<=4;i++)
 {
  Pop_L(&S,&z);
  printf("%d\t",z);
 }
  system("pause");
}

測試結果與線性棧的結果相同,如上圖測試結果。

------------------------------------------華麗分割線----------------------------------------------------------

學習數據結果記錄,棧的計數遍歷等操做思路與線性表相同。若有錯誤歡迎指正。

相關文章
相關標籤/搜索