数据结构与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;}



原创粉丝点击