数据结构与C语言实现(二)——堆栈和队列
来源:互联网 发布:硬盘录像机端口 编辑:程序博客网 时间:2024/04/30 03:32
#include <stdio.h>#include <stdlib.h>//这里是用数组实现堆栈的两种方式,第一种是单方向的,第二种是双方向的。#define MaxSize 100struct SNode{int data[MaxSize];int top;};typedef struct SNode *Stack;//用一个数组实现两个堆栈struct DNode{int data[MaxSize];int top1;int top2;};typedef struct DNode* DStack;//入栈void Push(Stack PtrS, int item){if (PtrS->top == MaxSize - 1){printf("Error:Stack Full");return;}else{PtrS->top++;//栈指针向上移动PtrS->data[PtrS->top] = item;//站指针指向地址存放新的数据return;}}//出栈int Pop(Stack PtrS){if (PtrS->top == -1){printf("Error:Stark is Empty");return -1;//返回-1说明为空}return (PtrS->data[PtrS->top--]);}//从数组的两端向堆栈中存放数据void DPush(DStack PtrS, int item, int Tag)//Tag用于判断是堆栈1还是堆栈2{if (PtrS->top2 - PtrS->top1 == 1){printf("Error:Full of the Stark");}else{if (Tag == 1){PtrS->top1++;PtrS->data[PtrS->top1] = item;}else{PtrS->top2--;PtrS->data[PtrS->top2] = item;}}}//从两个堆栈的指针处向两端释放一个数据int DPop(DStack PtrS, int Tag){if (Tag == 1)if (PtrS->top1 == -1){printf("Error:Stark 1 is Empty");return -1;}else return(PtrS->data[PtrS->top1--]);elseif (PtrS->top2 == MaxSize){printf("Error:Stark 2 is Empty");return -1;}else{return(PtrS->data[PtrS->top2++]);}}int main(){Stack new_stack = (Stack)malloc(sizeof(struct SNode));new_stack->top = -1;Push(new_stack,5);Push(new_stack,10);printf("%d \n", Pop(new_stack));printf("%d \n", Pop(new_stack));//结果应该先出5,再出10DStack new_dstack = (DStack)malloc(sizeof(struct DNode));new_dstack->top1 = -1;new_dstack->top2 = MaxSize;DPush(new_dstack, 8, 1);DPush(new_dstack, 9, 1);DPush(new_dstack, 12, 2);DPush(new_dstack, 13, 2);printf("%d ", DPop(new_dstack, 1));printf("%d ", DPop(new_dstack, 1));printf("%d ", DPop(new_dstack, 2));printf("%d ", DPop(new_dstack, 2));//输出应该为9 8 13 12return 0;}
第二种是通过链表实现堆栈的操作。
#include <stdio.h>#include <stdlib.h>/*用链表实现堆栈的时候,实质操作的就是头节点后面的那个节点。Push就是插入,将一个新的内存空间插入在头结点之后Pop就是删除,将头后面的节点删除我们可以形象的理解成,数组的堆栈的底部在下面,成 u 型。入栈数据从上插入,出栈指针下移,从上往下数据出栈。链表实现堆栈的底部在上面,成 n 型。指针不动,入栈数据从下方插入,出栈从下方拿出。*/struct SNode {int data;struct SNode *next;};typedef struct SNode* PtrS;typedef struct SNode Stack;PtrS CreateStack(){PtrS new_stack = (PtrS)malloc(sizeof(Stack));new_stack->next = NULL;return new_stack;}int IsEmpty(PtrS S){return (S->next == NULL);}void Push(int item, PtrS S){PtrS TmpCell;TmpCell = (PtrS)malloc(sizeof(Stack));TmpCell->data = item;TmpCell->next = S->next;S->next = TmpCell;}int Pop(PtrS S){PtrS FirstCell;//用于删除第一个有内容的节点int TopData;if (IsEmpty(S)){printf("Error:Stack is empty");return NULL;}else{FirstCell = S->next;S->next = FirstCell->next;TopData = FirstCell->data;free(FirstCell);return TopData;}}
最后一个是队列,在这个例子里,给出了用数组所构成的循环队列和用链表构建的队列
#include <stdio.h>#include <stdlib.h>////用数组实现循环队列//#define MAXSIZE 100////struct QNode//{//int data[MAXSIZE];//int front;//指向头一个元素的再前一个,删除时后移//int rear;//添加的时候rear++//};//typedef struct QNode* Queue;///*//两种方法解决rear == front时判断是空还是满。//1.使用额外的标记:size或者tag//2.只使用MAXSIZE-1的方案//*///void AddQ(Queue PtrQ, int item)//{//if ((PtrQ->rear + 1) % MAXSIZE == PtrQ->front)//{//printf("Error:Queue is Full");//return;//}//else//{//PtrQ->rear = (PtrQ->rear + 1) % MAXSIZE;//注意rear的初始值为-1,front也为-1.对maxsize求余正好得到0到maxsize-1。//PtrQ->data[PtrQ->rear] = item;//}//}////int ExitQ(Queue PtrQ)//{//if (PtrQ->front == PtrQ->rear)//{//printf("Error:The Queue is Empty");//return -1;//}//else//{//PtrQ->front = (PtrQ->front + 1) % MAXSIZE;//不能只用PtrQ->front++,因为要考虑到循环队列的循环性质。//return PtrQ->data[PtrQ->front];//}//}//用单链表实现队列,问题:front和rear应该分别指向链表的哪一头//链表头做插入,front,链表尾做删除,rear。如果链表尾做front,会导致删除后不知道前一个在哪。(可以通过双向链表解决)struct Node{int data;struct Node *next;};typedef struct Node* PNode;struct QNode //链队列结构{PNode rear;//指向队尾的节点·PNode front;//指向队首的节点};typedef struct QNode *Queue;Queue PtrQ;//不带头节点的链式队列的出队操作int ExitQ(){PNode FrontCell;int item;if (PtrQ->front == NULL){printf("Error:The Queue is Empty");return -1;}FrontCell = PtrQ->front;if (PtrQ->front == PtrQ->rear)//说明只有一个元素PtrQ->front = PtrQ->rear = NULL;//删除后都指向空else PtrQ->front = PtrQ->front->next;//将front向后移动一个节点item = FrontCell->data;//将数据取出free(FrontCell);//将原来的front节点的内存空间释放return item;//返回数据}//不带头节点的链式队列的入队操作void AddQ(int item){//typedef struct Node* PNode;PNode New_Node = (PNode)malloc(sizeof(struct Node));//创建一个节点,准备插入至队列尾New_Node->next = NULL;//Queue PtrQ;之前申明了,是一个全局变量,表示整个队列。//如果没申明,那在函数入口参数应该有一个:Queue PtrQ,用来说明插入到什么队列中,PtrQ->rear->next = New_Node;//添加至队列的尾巴PtrQ->rear = New_Node;//指向新的队尾,也可以用PtrQ->rear = PtrQ->rear->next;New_Node->data = item;}
阅读全文
0 0
- 数据结构与C语言实现(二)——堆栈和队列
- 数据结构与算法——在一个数组中实现两个堆栈(C语言)
- c语言实现通用数据结构(二):通用队列
- 数据结构C语言实现系列——链式堆栈
- 数据结构(四)——队列(C语言实现)
- 数据结构——队列的链式实现(C语言)
- JavaScript学习总结(二十一)——使用JavaScript的数组实现数据结构中的队列与堆栈
- 数据结构——队列、堆栈和哈希表
- 数据结构归纳——队列和堆栈
- 数据结构——堆栈和队列
- 数据结构:队列(C语言实现)
- 数据结构(C语言)实现循环队列
- 数据结构实现链式队列(C语言)
- 数据结构:循环队列(C语言实现)
- 数据结构:循环队列(C语言实现)
- 数据结构:循环队列(C语言实现)
- 数据结构:循环队列(C语言实现)
- 数据结构:循环队列(C语言实现)
- 一个web项目web.xml的配置操作
- 线性表综合实验之单链表的实现
- Spark(黑名单过滤)
- 哈夫曼树
- 动态规划 0-1背包问题和时间轴问题
- 数据结构与C语言实现(二)——堆栈和队列
- JPEG解码程序(带中文注释)
- Git配置用户名密码
- 关于VirtualBox记录
- Eclipse怎么汉化?
- CodeForces 864B Polycarp and Letters
- Linux Unit2--Linux系统结构
- vs无法打开文件“glut32“解决方案
- BZOJ 3712 Fiolki (倍增LCA)