栈与队列、链表

来源:互联网 发布:上海 逛街 知乎 编辑:程序博客网 时间:2024/06/06 13:04

栈(stack)是一种后进后出的数据结构,栈限定为只能在一端进行插入和删除操作。栈上的insert操作称为压入(push),而无元素参数的delete操作称为弹出(pop)。用一个一维数组S[ n]和一个指向栈顶的变量top就可以实现栈。S[0]是栈底元素,S[S.top]是栈顶元素。当S.top=0时,栈内不包含任何元素,即栈是空的。如果试图对一个空栈进行弹出操作,则称为栈下溢(underflow)。如果S.top超过了n,则称为栈上溢(overflow)。

队列

队列(queue)是一种特殊的线性结构,它只允许在队列的首部(head)进行删除,这称为“出队”,而在队列的尾部(tail)进行插入操作,这称为“入队”。当队列中没有元素时(即head==tail),称为空队列。
队列的实现是一种先进先出策略。利用数组Q[n]和两个变量head、tail就可以实现队列。Q.head指向队头元素,Q.tail指向下一个元素将要插入的位置。初始时有Q.head=Q.tail=1。如果试图从空队列中删除一个元素,则队列发生下溢。当Q.head=Q.tail+1时,队列是满的,此时若试图插入一个元素,则队列发生上溢。
栈与队列练习

#include "stdio.h"struct queue    //实现队列{    int data[1000];    int head;    int tail;};struct stack    //实现栈{    int data[10];    int top;};void main(){    struct queue q1,q2;    struct stack s;    int mark[10]={0};    q1.head = 1;    //初始化    q1.tail = 1;    q2.head = 1;    q2.tail = 1;    s.top = 0;    printf("给A同学发六张牌:");     //发牌阶段    for (int i=1;i<=6;i++)    {        scanf("%d",&q1.data[q1.tail]);    //读入一个数到尾部        q1.tail++;    }    printf("给B同学发六张牌:");         for (int i=1;i<=6;i++)    {        scanf("%d",&q2.data[q2.tail]);            q2.tail++;    }    while(q1.head<q1.tail && q2.head<q2.tail)   //游戏开始    {        int t = q1.data[q1.head];   //A同学出一张牌        if (mark[t]==0)        {            q1.head++;            s.top++;            s.data[s.top]=t;            mark[t]=1;  //添加标记        }else        {            q1.head++;            q1.data[q1.tail]=t;            q1.tail++;            while(s.data[s.top]!=t)            {                mark[s.data[s.top]]=0;   //取消标记                q1.data[q1.tail]=s.data[s.top];                q1.tail++;                s.top--;            }            mark[s.data[s.top]]=0;   //取消标记            q1.data[q1.tail]=s.data[s.top];            q1.tail++;            s.top--;        }        if (q1.head==q1.tail)  break;        t = q2.data[q2.head];   //B同学出一张牌        if (mark[t]==0)        {            q2.head++;            s.top++;            s.data[s.top]=t;            mark[t]=1;  //添加标记        }else        {            q2.head++;            q2.data[q2.tail]=t;            q2.tail++;            while(s.data[s.top]!=t)            {                mark[s.data[s.top]]=0;   //取消标记                q2.data[q2.tail]=s.data[s.top];                q2.tail++;                s.top--;            }            mark[s.data[s.top]]=0;   //取消标记            q2.data[q2.tail]=s.data[s.top];            q2.tail++;            s.top--;        }        if (q2.head==q2.tail)          break;          }    if (q2.head==q2.tail)    {        printf("A同学获胜\n");        printf("A同学的牌手中的牌是:");        for (int i=q1.head;i<q1.tail-1;i++)        printf("%d  ",q1.data[i]);        if (s.top>0)        {            printf("\n桌上的牌是:");            for (int i=1;i<s.top;i++)                printf(" %d",s.data[i]);        }        else            printf("\n桌上已经没有牌了");    }else    {        printf("B同学获胜\n");        printf("B同学的牌手中的牌是:");        for (int i=q2.head;i<q2.tail-1;i++)            printf("%d  ",q2.data[i]);        if (s.top>0)        {            printf("\n桌上的牌是:");            for (int i=1;i<s.top;i++)                printf(" %d",s.data[i]);        }        else            printf("\n桌上已经没有牌了");    }    system("pause");    return ; }

链表

链表(linked list)是各对象按线性顺序排列的数据结构。链表的顺序是由各个对象里的指针决定的。
双向链表L(double linked list):每个元素都是一个对象,每个对象有一个关键字key和两个指针:next和prev。假设X为链表的一个元素,X.next指向它在链表中的后继元素,X.prev则指向它的前驱元素。如果X.prev=NULL,则元素X没有前驱,因此是链表的第一个元素,即链表的头(head)。如果X.next=NULL,则元素X没有后继,因此是链表的最后一个元素,即链表的尾(tail)。属性L.head指向链表的第一个元素。如果L.head=NULL,则链表为空。
如果一个链表是单链接的(singly linked),则省略每个元素中的prev指针。
指针实现链表

#include <stdio.h>#include <stdlib.h>struct node{    int data;    struct node *next;};void main(){    struct node *head,*p,*q,*t;    int i,n,a;    printf("你想输入几位数?\n");    scanf("%d",&n);    head = NULL;    printf("请输入%d位数:",n);    for (i=1;i<=n;i++)    {        scanf("%d", &a);        p=(struct node*)malloc(sizeof(struct node));        p->data = a;        p->next = NULL;        if (head==NULL)        {            head = p;        }else        {            q->next = p;            }        q = p;    }        printf("输入要插入的数\n");        scanf("%d ",&a);        t = head;        while(t!=NULL)        {            if (t->next==NULL||t->next->data>a)            {                p = (struct node *)malloc(sizeof(struct node));                p->data = a;                p->next = t->next;                t->next = p;                break;            }            t = t->next;        }        t = head;        while(t!=NULL)        {            printf("%d ",t->data);            t = t->next;        }        system("pause");        return ; }

数组实现模拟链表

#include <stdio.h>#include <stdlib.h>void main(){    int data[101],right[101];    int i,n,t,len;    printf("你想输入几位数?\n");    scanf("%d",&n);    printf("请输入%d位数:",n);    for (i=1;i<=n;i++)    {        scanf("%d",&data[i]);    }    len = n;    for (i=1;i<=n;i++)    {        if (i!=n)            right[i]=i+1;        else            right[i]=0;    }    len++;    printf("输入要插入的数\n");    scanf("%d",&data[len]);    t = 1;    while (t!=0)    {        if (data[right[t]]>data[len])        {            right[len] = right[t];            right[t] = len;            break;        }        t = right[t];    }    t=1;    while(t!=0)    {        printf("%d ",data[t]);        t = right[t];    }    system("pasue");    return ; }

参考文献:
《算法导论》
《啊哈!算法》

原创粉丝点击