终于有可以有时间写点数据结构的学习总结了,前段时间一直在紧张的忙一些项目,都没有空出时间来学习数据结构,现在终于可以稍微喘口气了,还是数据结构有意思,这两天看了点栈的东西,写下来总结一下,有错误的地方希望看到的朋友指出来,感激不尽。
根据学习,栈就是一种线性数据结构,栈的运算只能在表的一段进行,所以这种数据结构具有“后进先出”的特点。
接下来是栈的c语言实现。其中栈由一个top节点和bottom节点组成,这两个节点分别指向栈的顶部和底部。其中栈的组成结点是由结构体实现,结构体由数据库和指向下一个结点的指针域构成,下面是结点的c语言实现:
1 /* 2 定义实现栈的结点 3 */ 4 typedef struct Node{ 5 int data; 6 struct Node * pNext; 7 }NODE,* PNODE;
有了实现栈的结点,那么接下来就是该如何实现栈(具体的解释看代码):
1 /* 2 定义栈的结构,此处采用链表实现静态栈,所以仅仅需要给出栈的头部指针和底部指针即可 3 */ 4 typedef struct Strack{ 5 PNODE pTop; 6 PNODE pBottom; 7 }STRACK,* PSTRACK;
栈的基本操作:栈的初始化,压栈、栈的遍历、出栈等操作
1 /* 2 对栈初始化的函数 3 对栈初始化仅仅是令栈中的top和bottom指针指向一个确定的地址,并且此地址指向的是栈的头结点(头结点的引入可以 4 大大方便对栈的操作)。 5 */ 6 void init_strack(PSTRACK pS){ 7 pS->pTop=(PNODE)malloc(sizeof(NODE)); //定义一个新结点,这个结点就是栈的头结点,并且让pTop指向这个结点 8 if(pS->pTop==NULL){ 9 printf("内存分配失败"); 10 exit(-1); 11 } 12 else{ 13 pS->pBottom=pS->pTop; //令bottom和top都指向头结点,则初始化栈完成,栈中没有任何有效结点 14 pS->pTop->pNext=NULL; 15 } 16 17 } 18 19 /* 20 压栈函数 21 因为栈具有“先进后出、后进先出”的特性,所以,在将元素压入栈时,也只能将栈压入栈的顶部 22 由此,压栈函数就是令栈的top指针指向新结点,新结点的指针域指向未压入栈时的最顶部的元素。 23 */ 24 int push(PSTRACK pS,int val){ 25 PNODE pNew=(PNODE)malloc(sizeof(NODE)); //定义一个新结点 26 if(pNew->pNext==NULL){ 27 printf("内存分配失败"); 28 exit(-1); 29 } 30 pNew->data= val; 31 pNew->pNext=pS->pTop; //指针赋值的顺序不可以乱,为保证top所指向的地址不丢失,所以首先让新结点的指针域指向pS->pTop所指向的结点 32 pS->pTop=pNew; //令top指针指向新的结点 33 return 0; //0表示当前push成功 34 } 35 36 /* 37 栈的遍历函数 38 因为只是遍历输出,所以不能破坏栈原有的结构,所以我们只有定义一个新的结点p,让其指向栈顶元素, 39 然后遍历下移一个输出其指向的元素的值 ,循环条件就是p=ps->pBottom 40 */ 41 void traverse(PSTRACK ps){ 42 PNODE p=ps->pTop; //让新定义的结构体指针指向栈顶元素 43 while(p!=ps->pBottom){ 44 printf("%d ", p->data); 45 p=p->pNext; //让当前指针指向当前节点的下一个结点 46 } 47 printf("\n"); 48 return; 49 } 50 51 52 /* 53 判断当前栈是否为空的函数 54 若为空,返回true 55 否则,返回false 56 */ 57 bool isEmpty(PSTRACK ps){ 58 if(ps->pTop==ps->pBottom){ 59 return true; 60 } 61 else{ 62 return false; 63 } 64 } 65 66 /* 67 弹栈函数:弹栈简单的说就是将第一个数值弹出,然后将ps->pTop指向原第一个结点的下一个结点(即弹栈后的第一个结点), 68 然后在将被弹出的元素在内存中释放掉。 69 */ 70 bool pop(PSTRACK ps,int *pVal){ 71 if(isEmpty(ps)){ //判断当前栈是否为空,若为空,则返回false 72 return false; 73 } 74 else{ 75 PNODE p=ps->pTop; //定义一个结点,这个结点在每次弹栈时都是指向栈顶,这样可以保证不会造成被弹出元素的丢失 76 ps->pTop=p->pNext; //让top结点指向栈顶元素 77 *pVal=p->data; 78 free(p); //将被弹出元素释放 79 p=NULL; 80 return true; 81 } 82 }
上述就实现了对栈的基本操作,当然具体的应用还要看具体的算法要求。
时间: 2024-10-24 00:59:20