栈和队列的顺序存储和链式存储
来源:互联网 发布:britney spears 知乎 编辑:程序博客网 时间:2024/06/06 07:33
一,栈
A.顺序存储
内容:此线性表采用顺序存储,实现了初始化、建表、查找、删除、打印,清空,销毁,返回前去后继等功能。
---------------函数功能实现------------------//构造一个空栈Sint InitStack(SqStack *S){ printf("\n*****创建空栈*****\n"); (*S).base = (int *)malloc(STACK_INIT_SIZE*sizeof(int)); if(!(*S).base) {printf("\n--空间申请失败--\n");return ERROR;} (*S).top = (*S).base; (*S).stacksize = STACK_INIT_SIZE; printf("\n--空栈创建成功--\n"); return OK;}//销毁栈S:S不再存在int DestroyStack(SqStack *S){ printf("\n*****销毁栈*****\n"); free((*S).base); (*S).top = (*S).base=NULL;//将元素清空 (*S).stacksize=0;//没有元素,则stacksize置0 printf("\n--销毁成功--\n"); return TRUE;}//置空栈:把S置为空栈int ClearStack(SqStack *S){ printf("\n*****清空栈*****\n"); (*S).top = (*S).base;//即栈顶和栈底指针为同一位置 printf("\n--清空成功--\n"); return TRUE;}//判空栈:若栈S为空S栈,则返回TRUE,否则返回FALSEint StackEmpty(SqStack *S){ printf("\n*****栈的判空*****\n"); if((*S).top == (*S).base) {printf("\n--栈为空--\n");return TRUE;} else{printf("\n--栈不为空--\n");return FALSE;} return FALSE;}//栈长:返回S的元素个数,即栈的长度int StackLength(SqStack *S){printf("\n*****计算长度*****\n");printf("\n--栈的长度为:%d--\n",(*S).top - (*S).base); return (*S).top - (*S).base;//栈顶指针指向最后一个元素的下一位置}//若栈S不空,则用e返回S的栈顶元素;否则返回 ERRORint GetTop(SqStack *S,int e){printf("\n*****查找栈顶*****\n");if((*S).top == (*S).base) {printf("\n--栈为空,无法查找栈顶--\n");return ERROR;} e=*((*S).top-1);printf("\n--栈顶为:%d--\n",e); return e;}//进栈:插入元素e为新的栈顶元素int Push(SqStack *S,int e){printf("\n*****从栈顶进栈*****\n"); if((*S).top - (*S).base >= (*S).stacksize)//数据过多,栈满,增加存储空间 { (*S).base=(int *)realloc((*S).base,((*S).stacksize+STACKINCREMENT)*sizeof(int)); //realloc增加空间之后,栈内数据不变,但会被复制到新的基址中,原内存块会被realloc释放 //如果可以直接在原先的内存块的后面增加数据的话,realloc就不用上面的那种方式了,但是前提是空间足够 if (!(*S).base) return ERROR; (*S).top = (*S).base + (*S).stacksize;//扩容成功后,按照惯例栈顶指针指向最后一个元素的下一位置 (*S).stacksize += STACKINCREMENT;//将定义的存储空间追加空间 } *(*S).top++=e;//将参数数据逐个进栈printf("\n--%d进栈--\n",e); return OK;}//退栈:若栈S不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERRORint Pop(SqStack *S,int e){ printf("\n*****从栈顶出栈*****\n"); if((*S).top == (*S).base) {printf("\n--栈为空--\n");return ERROR;} e=*(--((*S).top));//将栈顶指针前移一位,然后将当前位置上的数据返回给e,完成删除栈顶元素的操作 printf("\n--%d出栈--\n",e); return OK;}//输出栈:从栈底到栈顶依次输出栈内元素int StackTraverse(SqStack *S){printf("\n*****遍历输出*****\n\n"); int *p = NULL; int length = 0;int i;if((*S).top == (*S).base && (*S).base != NULL){printf("\n--栈为空,无法遍历输出--\n");}if((*S).base == NULL){printf("\n--栈不存在,无法遍历输出--\n");return ERROR;} length = StackLength(S);printf("\n\n位置 | ");for(i = 1;i <= length;i++){if(i == 1) printf("栈底");else{ printf("\t"); if(i == length) printf("栈顶");}} printf("\n-----------------------------------------------\n"); printf("数据 | "); if((*S).top != (*S).base) //栈不为空时 { for(p= (*S).base;p <= (*S).top-1;p++) printf("\t%d",*p); }printf("\n"); return OK;}——————————栈顺序存储主函数(测试)————————————#include "G.h"void main(){SqStack myS;SqStack *S = &myS; int e;//创建空栈InitStack(S);//判空StackEmpty(S);//计算长度StackLength(S);//进栈:插入数据printf("\n请输入进栈数据:\n");scanf("%d",&e);while(e != 0){Push(S,e);printf("\n请输入进栈数据:\n"); scanf("%d",&e);}StackEmpty(S);//StackLength(S);//输出栈内数据 StackTraverse(S); //找出栈顶元素GetTop(S,e);//退栈Pop(S,e);GetTop(S,e);StackLength(S); StackTraverse(S);//清空栈内数据ClearStack(S);StackEmpty(S);//StackLength(S);GetTop(S,e);StackTraverse(S);//销毁栈DestroyStack(S);StackTraverse(S);}B.链式存储————————函数实现—————————void InitStack(DAT *S){printf("\n*****创建空栈*****\n"); (*S).base = (sqStack *)malloc(sizeof(sqStack)); (*S).top = (*S).base;printf("\n--创建空栈成功--\n");}void ClearStack(DAT *S){printf("\n*****清空栈*****\n");sqStack *p = (*S).base;while(p != (*S).top){printf("\n--清除数据:%d--\n",p -> data);p = p -> next;free((*S).base);(*S).base = p;}printf("\n--清空栈成功--\n");}void DestroyStack(DAT *S){printf("\n*****销毁栈*****\n");sqStack *p = (*S).base;while(p != (*S).top){p = p -> next;free((*S).base);(*S).base = p;}(*S).base = NULL;//将数据清空之后,还要将栈的基底指针置空printf("\n--销毁栈成功--\n");}void Push(DAT *S,int e){printf("\n*****数据进栈*****\n");printf("\n请输入进栈数据:\n"); scanf("%d",&e);while(e != 0){sqStack *p = NULL;//p指针的作用为记录当前栈顶的位置,方便新栈顶的定位(即p的下一个)p = (*S).top; (*S).top -> data = e;//printf("\n--%d进栈--\n",*((*S).top));//printf("\n--top的当前位置1:%d--\n",((*S).top));(*S).top = (sqStack *)malloc(sizeof(sqStack)); p -> next = (*S).top;//printf("\n--top的当前位置2:%d--\n",((*S).top));printf("\n请输入进栈数据:\n"); scanf("%d",&e);}}int Pop(DAT *S,int e){printf("\n*****数据出栈*****\n");if((*S).base == (*S).top){printf("\n--栈为空,无法将数据出栈--\n");return FALSE;}sqStack *p = (*S).base; while(p -> next != (*S).top) p = p -> next;e = p -> data;printf("\n--%d出栈--\n",e);(*S).top = p; return OK;}int GetTop(DAT *S,int e){printf("\n*****查找栈顶*****\n");if((*S).base == (*S).top){printf("\n--栈为空,无法查找栈顶元素--\n");return FALSE;}sqStack *p = (*S).base;while(p -> next != (*S).top) p = p -> next;e = p -> data;printf("\n--栈顶元素为:%d--\n",e);return e;}int StackEmpty(DAT *S){ printf("\n*****栈的判空*****\n");if((*S).base == (*S).top){printf("\n--栈为空--\n");return TRUE;}else{printf("\n--栈不为空--\n");return FALSE;}}int StackLength(DAT *S){printf("\n*****栈的长度*****\n");int length = 0;sqStack *p = (*S).base;while(p != (*S).top){length++;p = p -> next;}printf("\n--栈的长度为:%d--\n",length);return length;}int StackTraverse(DAT *S){printf("\n*****遍历输出*****\n");if((*S).base == (*S).top && (*S).base != NULL){printf("\n--栈为空,无法遍历输出--\n");return FALSE;}if((*S).base == NULL){printf("\n--栈不存在,无法遍历输出--\n");return FALSE;} sqStack *p = (*S).base;printf("\n位置 | 栈底");printf("\n----------------------------------------------\n");printf("数据 | ");while(p != (*S).top){printf("%d ", p -> data);p = p -> next;}printf("栈顶");printf("\n");}—————————————————主函数———————————————#include "K.h"void main(){int e;DAT myS; DAT *S = &myS;//创建空栈InitStack(S);//判空StackEmpty(S);//进栈Push(S,e);//返回栈顶元素GetTop(S,e);//计算栈的长度 StackLength(S);StackEmpty(S);//遍历输出StackTraverse(S);//出栈Pop(S,e);StackTraverse(S);GetTop(S,e); StackEmpty(S);//清空栈ClearStack(S);StackTraverse(S); StackEmpty(S);//销毁栈 DestroyStack(S);StackTraverse(S);}
二.队列
A.顺序存储
内容:此线性表采用链式存储,实现了初始化、建表、查找、删除、打印,清空,销毁,返回前去后继等功能。
————————————队列基本函数实现—————————————int InitQueue(sqQueue *Q){printf("\n*****创建空队*****\n");(*Q).base = (int *)malloc(MAXQSIZE * sizeof(int));if(!(*Q).base) exit(OVERFLOW);(*Q).front = (*Q).rear = 0;(*Q).queuesize = MAXQSIZE;//初始分配空间为3printf("\n--空队创建成功--\n");return OK;}void DestroyQueue(sqQueue *Q){printf("\n*****销毁队列*****\n");free((*Q).base);//存储数据的空间完全释放(*Q).base = NULL;//指针置空(*Q).queuesize = 0;//当前分配的空间数目置空printf("\n--销毁成功--\n");}void ClearQueue(sqQueue *Q){printf("\n*****清空队列*****\n");(*Q).front = (*Q).rear = 0;(*Q).queuesize = 0;//为了防止在清空数据之后再将数据进队是发生错误,将当前分配的空间数置零printf("\n--数据清空成功--\n");}int EnQueue(sqQueue *Q,int e){printf("\n*****数据进队*****\n");if((*Q).rear - (*Q).front == (*Q).queuesize)//数据个数等于当前分配的空间数目的话,队列满载{ (*Q).base=(int*)realloc((*Q).base,((*Q).queuesize + QUEUEINCREMENT)*sizeof(int)); if(!(*Q).base) exit(OVERFLOW); //存储分配失败 (*Q).queuesize += QUEUEINCREMENT; //队空间大小增加 printf("\n--系统空间不足,自动增加2个单位--\n");} (*Q).base[(*Q).rear] = e; printf("\n--%d进队--\n",(*Q).base[(*Q).rear]); (*Q).rear++;return e;}int DeQueue(sqQueue *Q,int e){printf("\n*****数据出队*****\n");if((*Q).front == (*Q).rear){printf("\n--队列为空,无法出队--\n");return FALSE;}e = (*Q).base[(*Q).front];(*Q).front++;(*Q).queuesize--;//分配空间减一printf("\n--%d出队--\n",e);return e;}int GetHead(sqQueue *Q,int e){printf("\n*****查找队头*****\n");if((*Q).front == (*Q).rear && (*Q).base != NULL){printf("\n--队列为空,无法查找队头元素--\n");return FALSE;}if((*Q).base == NULL){printf("\n--队列不存在,无法查找队头元素--\n");return FALSE;} e = (*Q).base[(*Q).front];printf("\n--队头元素为:%d--\n",e);return e;}int QueueLength(sqQueue *Q){if((*Q).base == NULL) {printf("\n--队列不存在,无法计算长度--\n");return FALSE;}printf("\n*****计算长度*****\n");printf("\n--队列长度为:%d--\n",(*Q).rear - (*Q).front);return (*Q).rear - (*Q).front;}int QueueEmpty(sqQueue *Q){printf("\n*****队列判空*****\n");if((*Q).front == (*Q).rear){printf("\n--队列为空--\n");return TRUE;}else{printf("\n--队列不为空--\n");return FALSE;}}int QueueTraverse(sqQueue *Q){printf("\n*****队列输出*****\n\n");int i;if((*Q).front == (*Q).rear && (*Q).base != NULL){printf("\n--队列为空--\n\n");}if((*Q).base == NULL){printf("\n--队列不存在,无法遍历输出--\n");return FALSE;}printf("位置 | ");printf("队头");printf("\n-----------------------------------------------\n");printf("数据 | "); for(i = (*Q).front;i < (*Q).rear;i++){printf("%d ",(*Q).base[i]);}printf("队尾\n\n");return OK;}—————————主函数——————————#include "L.h"void main(){int e;sqQueue myQ;sqQueue *Q = &myQ;//创建空队InitQueue(Q);//队列判空QueueEmpty(Q);//计算长度 QueueLength(Q);//查找队头GetHead(Q,e);//数据进队printf("\n请输入进队数据:\n");scanf("%d",&e);while(e != 0){ EnQueue(Q,e); printf("\n请输入进队数据:\n"); scanf("%d",&e);} //遍历输出QueueEmpty(Q);QueueLength(Q);QueueTraverse(Q);GetHead(Q,e);//数据出队DeQueue(Q,e);QueueLength(Q); QueueTraverse(Q);GetHead(Q,e);//销毁//DestroyQueue(Q);//QueueTraverse(Q);//清空ClearQueue(Q);QueueTraverse(Q);GetHead(Q,e);}B.链式存储————————————队列链式函数实现——————————————//创建空队int InitQueue(dat *Q){printf("\n*****进入创建空队函数*****\n");(*Q).front = (*Q).rear = (DAT *)malloc(sizeof(DAT));if(!(*Q).front) {printf("\n--空队创建失败--\n");exit(OVERFLOW);}(*Q).front -> next = NULL;printf("\n--空队创建成功--\n");return OK;}//录入数据dat *CreatQueue(dat *Q){printf("\n*****进入数据录入函数*****\n");int n,i;printf("\n请输入你要录入的数据个数:\n");scanf("%d",&n);for(i = 1;i <= n;i++){DAT *p = (DAT *)malloc(sizeof(DAT)); printf("\n请输入数据:\n"); scanf("%d",&p -> data);p -> next = NULL;(*Q).rear -> next = p;(*Q).rear = p;//printf("--队头:%d--",*((*Q).front -> next));//printf("--队尾:%d--\n",*((*Q).rear));} return Q; }//销毁队列void DestroyQueue(dat *Q){printf("\n*****进入销毁队列函数*****\n");while((*Q).front){(*Q).rear = (*Q).front -> next;free((*Q).front);(*Q).front = (*Q).rear;} printf("\n--销毁成功--\n");}//清空队列void ClearQueue(dat *Q){ //画图可以帮助理解 printf("\n*****进入清空队列函数*****\n");DAT *p = (*Q).front -> next;//p的初始位置为队头(有数据)while((*Q).front -> next){(*Q).rear = p;p = (*Q).rear -> next;//移动到最后,p = NULLprintf("\n--%d出队--\n",*((*Q).rear));free((*Q).rear);(*Q).rear = (*Q).front;(*Q).front -> next = p;//到最后p = NULL,所以刚好满足循环跳出的条件,且数据完全已被清空,表头指针也被保留了下来}free(p);printf("\n--清空完成--\n");}//队列判空int QueueEmpty(dat *Q){printf("\n*****进入队列判空函数*****\n");if((*Q).front == (*Q).rear){printf("\n--队列为空--\n");return TRUE;}else{printf("\n--队列不为空--\n");return FALSE;}}//计算队列长度int QueueLength(dat *Q){printf("\n*****进入计算长度函数*****\n");int length = 0;DAT *p = (*Q).front -> next;while(p != NULL){length++;p = p -> next;}printf("\n--队列的长度为:%d--\n\n",length);return length;}//返回队头int GetHead(dat *Q,int e){printf("\n*****进入返回队头函数*****\n");if((*Q).front == (*Q).rear){printf("\n--队列为空,无法查找队头元素--\n");return(FALSE);}DAT *p = (*Q).front -> next;e = p -> data; printf("\n--队头为:%d--\n",p -> data);return e;}//进队void EnQueue(dat *Q,int e){printf("\n*****进入进队函数*****\n");DAT *p = (DAT * )malloc(sizeof(DAT));if(!p) exit(OVERFLOW);p -> data = e;p -> next = NULL;(*Q).rear -> next = p;//用表尾指针进行增减操作更具有可靠性(因为表尾指针可以随着数据的增减而移动,而表头指针不行)(*Q).rear = p;}//出队int DeQueue(dat *Q,int e){printf("\n*****进入出队函数*****\n");DAT *p = (*Q).front -> next;DAT *q = p -> next;e = p -> data;printf("\n--%d出队--\n",e);(*Q).front -> next = q;if((*Q).front -> next == NULL) (*Q).front = (*Q).rear; return e;}//遍历输出int QueueTraverse(dat *Q){ printf("\n*****进入遍历输出函数*****\n");if((*Q).front == (*Q).rear && (*Q).front != NULL){printf("\n--队列为空--\n");return(FALSE);}if((*Q).front == NULL){printf("\n--队列不存在--\n");return(FALSE);}int length,i;DAT *p = (*Q).front -> next; length = QueueLength(Q);printf("位置 |"); printf("队头");printf("\n--------------------------------------\n");printf("数据 | ");while(p != NULL){printf("%d ",p -> data);p = p -> next;}printf("队尾"); printf("\n");return OK;}——————————————主函数——————————————————#include "J.h"void main(){int e;dat myQ;dat *Q = &myQ;//创建空队 InitQueue(Q);//判空 QueueEmpty(Q); //录入数据Q = CreatQueue(Q);//遍历输出QueueTraverse(Q); //销毁队列//DestroyQueue(Q);//QueueTraverse(Q);//清空队列ClearQueue(Q); QueueTraverse(Q);//返回队头GetHead(Q,e); //进队printf("\n请输入你要进队的数据:\n");scanf("%d",&e);while(e != 0){ EnQueue(Q,e);printf("\n请输入你要进队的数据:\n"); scanf("%d",&e);} QueueTraverse(Q); //出队DeQueue(Q,e);QueueTraverse(Q);}
三.循环队列
#include <stdio.h>#include <stdlib.h>#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define NULL 0#define OVERFLOW -2#define MAXSIZE 5 typedef struct{ int *base; int front; int rear; }SqQueue;int InitQueue(SqQueue *Q){printf("\n*****创建空队列*****\n"); (*Q).base=(int *)malloc(MAXSIZE*sizeof(int)); if(!(*Q).base) exit(OVERFLOW); (*Q).front = (*Q).rear = NULL; printf("\n--循环队列的默认空间为:4--\n");printf("\n--空表创建成功--\n"); return OK;}int creatQueue(SqQueue *Q){printf("\n*****录入数据*****\n");int n,i;printf("\n请输入你要存储的数据个数:\n"); scanf("%d",&n);printf("\n请输入数据:\n");for(i = 0;i < n;i++){scanf("%d",&(*Q).base[i]); (*Q).rear = (i+1)%MAXSIZE; if(((*Q).rear+1)%MAXSIZE == (*Q).front) { printf("\n--队列已满--\n");return FALSE;}}printf("\n--队头位置:%d--\n",(*Q).front);printf("\n--队尾位置:%d--\n",(*Q).rear);return TRUE;}int DestroyQueue(SqQueue *Q){ printf("\n*****销毁队列*****\n"); free((*Q).base); (*Q).base = NULL; printf("\n--销毁成功--\n"); return OK;}int ClearQueue(SqQueue *Q){ printf("\n****清空队列*****\n"); (*Q).rear = (*Q).front = NULL; printf("\n--清空成功--\n"); return OK;}int QueueLength(SqQueue *Q){ printf("\n*****计算队列长度*****\n");printf("\n--队列长度为:%d--\n", ((*Q).rear-(*Q).front+MAXSIZE)%MAXSIZE); return ((*Q).rear-(*Q).front+MAXSIZE)%MAXSIZE;}int QueueEmpty(SqQueue *Q){printf("\n*****队列是否为空*****\n"); if((*Q).front==(*Q).rear) {printf("\n--队列为空--\n");return TRUE;} //队列空 else return ERROR;}int GetHead(SqQueue *Q,int e){printf("\n*****返回队头元素*****\n"); if((*Q).front==(*Q).rear) {printf("\n--队列为空,无法查找队头元素--\n");return ERROR;} //队列空 e = (*Q).base[(*Q).front];printf("\n--队头元素为:%d--\n",e); return OK;}int EnQueue(SqQueue *Q,int e){int del;printf("\n*****插入队尾元素*****\n"); while(((*Q).rear+1)%MAXSIZE == (*Q).front) //队满后队头出队,新数据插入到队尾{ printf("\n--队列已满,队头出队--\n"); del = (*Q).base[(*Q).front]; (*Q).front = ((*Q).front+1) % MAXSIZE; printf("\n--已将队头元素:%d出队--\n",del);}//printf("\n--队头位置:%d--\n",(*Q).front);//printf("\n--队尾位置:%d--\n",(*Q).rear);printf("\n--插入的数据为:%d--\n",e); (*Q).base[(*Q).rear] = e; (*Q).rear =((*Q).rear+1) % MAXSIZE; return OK;}int DeQueue(SqQueue *Q,int e){printf("\n*****删除队头元素*****\n"); if((*Q).front == (*Q).rear) {printf("\n--队列为空,无法删除--\n");return ERROR;} e = (*Q).base[(*Q).front]; (*Q).front = ((*Q).front+1) % MAXSIZE; printf("\n--已将队头元素:%d删除--\n",e); return OK;}int QueueTraverse(SqQueue *Q){ int i = (*Q).front; if((*Q).base == NULL) {printf("\n--队列不存在,无法输出数据--\n");return ERROR;} else if((*Q).front == (*Q).rear && (*Q).base != NULL) {printf("\n--队列为空,无法输出数据--\n");return ERROR;} printf("\n队列如下:\n"); printf("-------------------------------------------------\n");printf("数据 | "); while(i != (*Q).rear){ printf("%d ",((*Q).base[i])); i = (i+1) % MAXSIZE;} printf("\n"); return OK;}#include "M.h"int main(){int i,e; SqQueue myQ; SqQueue *Q = &myQ; //创建队列 InitQueue(Q); QueueEmpty(Q);//判空 //录入数据 creatQueue(Q); QueueLength(Q); QueueTraverse(Q); //查找对头元素 GetHead(Q,e);//插入队尾元素printf("\n请输入你要插入的数值:\n");scanf("%d",&e);while(e != 0){ EnQueue(Q,e);QueueLength(Q); QueueTraverse(Q); printf("\n请输入你要插入的数值:\n"); scanf("%d",&e);} //删除队头元素 DeQueue(Q,e); QueueTraverse(Q);//清空队列 ClearQueue(Q); QueueEmpty(Q); QueueTraverse(Q); //销毁队列 DestroyQueue(Q); QueueTraverse(Q);}
- 队列的顺序存储和链式存储
- 栈和队列的顺序存储和链式存储
- 栈的顺序存储和链式存储
- 栈的顺序存储和链式存储
- 队列的顺序存储结构和链式存储结构
- 队列的顺序存储实现和链式存储实现
- 数据结构—队列的顺序和链式存储
- 顺序存储和链式存储的比较
- 顺序存储和链式存储
- C++栈的顺序存储和链式存储的实现
- 栈的顺序存储结构和链式存储结构
- 数据结构-【栈】的链式存储和顺序存储
- 栈的顺序存储结构和链式存储结构
- 栈的顺序存储实现和链式存储实现
- 数据结构-栈的顺序存储和链式存储
- Day17、链式存储结构动态分配内存、栈的顺序存储结构和链式存储结构
- 队列的链式存储与顺序存储
- 数据结构存储的顺序和链式对比
- Oracle 之 区分你的oracle是64位 or 32位?
- 基本语言细节--《The C++ Programming Language 》--(3)基本功能
- C++内嵌汇编(一):反汇编分析C++代码
- 一日一设计模式之C++篇(Build模式)
- Install “build-essential” on RHEL/CentOS and OpenSolaris
- 栈和队列的顺序存储和链式存储
- 苹果内训手册:如何在一线制造尖叫?
- C语言链表的概念-转发自苹果IOS开发者播客
- UML建模语言入门-视图,事物,关系,通用机制
- poj 3080 Blue jeans
- 根目录容量小也会导致Ubuntu is running in low-graphics mode.
- 在学习位图中遇到的一些常用的数据类型
- linux socket编程细节zz
- 针对高通平台的驱动开发CSDN博客