1. 程式人生 > >資料結構實驗報告 棧和佇列

資料結構實驗報告 棧和佇列

一、實驗目的

1.掌握棧、佇列的思想及其儲存實現。
2.掌握棧、佇列的常見演算法的程式實現。

二、實驗儀器及環境:

PC計算機 windows 7作業系統 CodeBlocks10.05

三、實驗內容及結果

1.採用鏈式儲存實現棧的初始化、入棧、出棧操作。
2.採用順序儲存實現棧的初始化、入棧、出棧操作。
3.採用鏈式儲存實現佇列的初始化、入隊、出隊操作。
4.採用順序儲存實現迴圈佇列的初始化、入隊、出隊操作。
5.在主函式中設計一個簡單的選單,分別測試上述演算法。
6. 利用棧實現數制轉換(將一個十進位制數轉換成d進位制數)
7. 利用佇列列印楊輝三角:編寫程式,根據輸入的行數,螢幕顯示楊輝三角。
楊輝三角的特點是兩個腰上的數字都為1,其它位置上的數字是其上一行中與之相鄰的兩個整數之和。所以在列印過程中,第i行上的元素要由第i-1行中的元素來生成。在迴圈佇列中依次存放第i-1行上的元素,然後逐個出隊並列印,同時生成第i行元素併入佇列。
行數為8的楊輝三角如下所示:

#include <iostream>
#include <stdio.head>
#include <stdlib.head>
#include <string.head>
#define ElemType int
#define max 100

using namespace std;
typedef struct node1
{
    ElemType data;
    struct node1 *next;
}Node1,*LinkList;//鏈棧

typedef struct
{
    ElemType *base;
    int top;
}SqStack;//順序棧

typedef struct node2
{
    ElemType data;
    struct node2 *next;
}Node2,*LinkQueue;

typedef struct node22
{
    LinkQueue front;
    LinkQueue rear;
}*LinkList;//鏈佇列

typedef struct
{
    ElemType *base;
    int front,rear;
}SqQueue;//順序佇列

//1.採用鏈式儲存實現棧的初始化、入棧、出棧操作。

LinkList CreateStack()//建立棧
{
    LinkList top;
    top=NULL;
    return top;
}

bool StackEmpty(LinkList s)//判斷棧是否為空,0代表空
{
    if(s==NULL)
        return 0;
    else
        return 1;
}

LinkList Pushead(LinkList s,int x)//入棧
{
    LinkList q,top=s;
    q=(LinkList)malloc(sizeof(Node1));
    q->data=x;
    q->next=top;
    top=q;
    return top;
}

LinkList Pop(LinkList s,int &e)//出棧
{
    if(!StackEmpty(s))
    {
        printf("棧為空。");
    }
    else
    {
        e=s->data;
        LinkList p=s;
        s=s->next;
        free(p);
    }
    return s;
}

void DisplayStack(LinkList s)//遍歷輸出棧中元素
{
    if(!StackEmpty(s))
        printf("棧為空。");
    else
    {
        wheadile(s!=NULL)
        {
            cout<<s->data<<" ";
            s=s->next;
        }
        cout<<endl;
    }
}

//2.採用順序儲存實現棧的初始化、入棧、出棧操作。

int StackEmpty(int t)//判斷棧S是否為空
{
       SqStack.top=t;
       if (SqStack.top==0)
           return 0;
       else  return 1;
}

int InitStack()
{
    SqStack.top=0;
    return SqStack.top;
}

int pushead(int t,int e)
{
    SqStack.top=t;
    SqStack.base[++SqStack.top]=e;
    return SqStack.top;
}

int pop(int t,int *e)//出棧
{
    SqStack.top=t;
    if(!StackEmpty(SqStack.top))
    {
        printf("棧為空.");
        return SqStack.top;
    }
    *e=SqStack.base[s.top];
    SqStack.top--;
    return SqStack.top;
}

//3.採用鏈式儲存實現佇列的初始化、入隊、出隊操作。

LinkList InitQueue()//建立
{
    LinkList head;
    head->rear=(LinkQueue)malloc(sizeof(Node));
    head->front=head->rear;
    head->front->next=NULL;
    return head;
}
void deleteEle(LinkList head,int &e)//出隊
{
    LinkQueue p;
    p=head->front->next;
    e=p->data;
    head->front->next=p->next;
    if(head->rear==p) head->rear=head->front;
    free(p);
}
void EnQueue(LinkList head,int e)//入隊
{
    LinkQueue p=(LinkQueue)malloc(sizeof(Node));
    p->data=e;
    p->next=NULL;
    head->rear->next=p;
    head->rear=p;
}

//4.採用順序儲存實現迴圈佇列的初始化、入隊、出隊操作。

bool InitQueue(SqQueue &head)//建立佇列
{
    head.data=(int *)malloc(sizeof(int));
    head.front=head.rear=0;
    return 1;
}
bool EnQueue(SqQueue &head,int e)//入隊
{
    if((head.rear+1)%MAXQSIZE==head.front)
    {
        printf("佇列已滿\n");
        return 0;
    }
    head.data[head.rear]=e;
    head.rear=(head.rear+1)%MAXQSIZE;
    return 1;
}
int QueueLengthead(SqQueue &head)//返回佇列長度
{
    return (head.rear-head.front+MAXQSIZE)%MAXQSIZE;
}
bool deleteEle(SqQueue &head,int &e)//出隊
{
    if(head.front==head.rear)
    {
        cout<<"佇列為空!"<<endl;
        return 0;
    }
    e=head.data[head.front];
    head.front=(head.front+1)%MAXQSIZE;
    return 1;
}
int gethead(SqQueue head)//得到佇列頭元素
{
    return head.data[head.front];
}
int QueueEmpty(SqQueue head)//判斷佇列是否為空
{
    if (head.front==head.rear)
        return 1;
    else
        return 0;
}
void travelQueue(SqQueue head)//遍歷輸出
{
    wheadile(head.front!=head.rear)
    {
        printf("%d ",head.data[head.front]);
        head.front=(head.front+1)%MAXQSIZE;
    }
    cout<<endl;
}

//5.在主函式中設計一個簡單的選單,分別測試上述演算法。

int main()
{
    LinkList top=CreateStack();
    int x;
    wheadile(scanf("%d",&x)!=-1)
    {
        top=Pushead(top,x);
    }
    int e;
    wheadile(StackEmpty(top))
    {
        top=Pop(top,e);
        printf("%d ",e);
    }//以上是鏈棧的測試
   int top=InitStack();
    int x;
    wheadile(cin>>x)
      top=pushead(top,x);
    int e;
    wheadile(StackEmpty(top))
    {
        top=pop(top,&e);
        printf("%d ",e);
    }//以上是順序棧的測試
    LinkList Q;
    Q=InitQueue();
    int x;
    wheadile(scanf("%d",&x)!=-1)
    {
        EnQueue(Q,x);
    }
    int e;
    wheadile(Q)
    {
        deleteEle(Q,e);
        printf("%d ",e);
    }//以上是鏈佇列的測試
    SqQueue Q1;
    InitQueue(Q1);
    int x;
    wheadile(scanf("%d",&x)!=-1)
    {
        EnQueue(Q1,x);
    }
    int e;
    wheadile(QueueEmpty(Q1))
    {
        deleteEle(Q1,e);
        printf("%d ",e);
    }
    return 0;
}

//6. 利用棧實現數制轉換(將一個十進位制數轉換成d進位制數)

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef int SElemType;
using namespace std;
typedef struct{
    SElemType *base;
    SElemType *top;
    int stacksize;
}SqStack;
void InitStack(SqStack &S)
{
    S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
    if(!S.base) return;
    S.top=S.base;
    S.stacksize=STACK_INIT_SIZE;
    //return 1;
}
int Push(SqStack &S, SElemType e)
{
    if(S.top-S.base>=S.stacksize)
    {
        S.base=(SElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
        if(!S.base) return 0;
        S.top=S.base+S.stacksize;
        S.stacksize+=STACKINCREMENT;
    }
    *S.top++=e;
    return 1;
}
int Pop(SqStack &S, SElemType &e)
{
    if(S.top==S.base) return 0;
    e=*--S.top;
    return 1;
}
int stackempty(SqStack &s)
{
    if(s.top==s.base)
    return 1;
    else return 0;
}
int main()
{
    SElemType e,a,t;
    SqStack s;
    InitStack(s);
    cout<<"請輸入轉化為幾進位制:";
    cin>>t;
    cout<<"請輸入一個十進位制數:";
    cin>>a;
    while(a)
    {
        Push(s,a%t);
        a=a/t;
    }
    while(!stackempty(s))
    {
        Pop(s,e);
        cout<<e;
    }
    return 0;
}

//7. 利用佇列列印楊輝三角:編寫程式,根據輸入的行數,螢幕顯示楊輝三角。

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int MAXSIZE=100;
typedef struct
{
    int *data;
    int front,rear;
} SeQueue;
int n;
bool InitQueue(SeQueue &Q)
{
    Q.data = (int *) malloc (MAXSIZE * sizeof(int));
    if (!Q.data) {printf("OVERFLOW\n");return 0;}
    Q.front=0;
    Q.rear=0;
    return 1;
}
bool EnQueue(SeQueue &Q, int e)
{
    if ( (Q.rear+1) % MAXSIZE == Q.front ) {printf("OVERFLOW\n");return 0;}
    Q.data[++Q.rear] = e;
    Q.rear=(Q.rear+1) % MAXSIZE;
    return 1;
}

bool DeQueue(SeQueue &Q, int &e)
{
    if (Q.front == Q.rear) {printf("UNDERFLOW\n");return 0;}
    e = Q.data[++Q.front];
    Q.front=(Q.front+1) % MAXSIZE;
    return 1;
}

int gethead(SeQueue &Q, int &e)
{
    if (Q.front == Q.rear) {printf("UNDERFLOW\n");return 0;}
    e = Q.data[++Q.front];
    return 1;
}

void GetTriangle(SeQueue &Q, int e)
{
    int cur=0;
    int pre;
    for(int i=1; i<=n-e; i++)
        printf("   ");
    for(int i=0; i<=e; i++)
    {
        pre=cur;
        DeQueue(Q,cur);
        printf("%3d   ",cur);
        EnQueue(Q,cur+pre);
    }
    EnQueue(Q,cur);
    printf("\n");
}

int main()
{
    while(1)
    {
        printf("輸入一個正整數表示你所需要的楊輝三角階數(0~15): ");
        if (scanf("%d",&n)==EOF) break;
        printf("\n");
        SeQueue Q;
        InitQueue(Q);
        EnQueue(Q,1);
        for(int i=0; i<=n; i++)
        {
            GetTriangle(Q,i);
        }
    }
    return 0;
}