栈和队列的顺序存储和链式存储

来源:互联网 发布: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);}



原创粉丝点击