棧和隊列(c語言數據結構實驗報告二)

實驗項目中文名稱:棧與隊列
實驗項目英文名稱:Stack and queue
實驗教學的內容或要求
1.編寫函數,採用鏈式存儲實現棧的初始化、入棧、出棧操作
2.編寫函數,採用順序存儲實現棧的初始化、入棧、出棧操作
3.編寫函數,採用鏈式存儲實現隊列的初始化、入隊、出隊操作
4.編寫函數,採用順序存儲實現隊列的初始化、入隊、出隊操作
5.編寫一個主函數,在主函數中設計一個簡單的菜單,分別調試上述算法

#include<stdio.h>
#include<windows.h>
#pragma warning(disable:4996)
//1.棧的順序結構
#define Stack_Size 50
typedef struct{
 int elem[Stack_Size];
 int top;
}SeqStack;
//a.初始化
void InitStack1(SeqStack *S){   
 S->top = -1;
 memset(S->elem, 0, sizeof(S->elem));
}
//b.進棧
int Push1(SeqStack *S, int x)  
{
 if (S->top == Stack_Size - 1){   //棧滿
  return -1;
 }
 else{
  S->top++;
  S->elem[S->top] = x;
  return 1;
 }
 return 0;
}
//c.出棧
int Pop1(SeqStack *S, int *x){   
/*將棧S的棧頂元素彈出,放到x所指向的存儲空間中*/
 if (S->top == -1){     
  return -1;
 }
 else{
  *x = S->elem[S->top];
  S->top--;     //修改棧頂指針
  return *x;
 }
 return 0;
}
//d.取棧頂元素
int GetTop1(SeqStack *S, int *x){ 
/*將棧S的棧頂元素彈出,放到x所指向的存儲空間中,但是棧頂指針保持不變*/
 if (S->top == -1){
  return -1;
 }
 else{
  *x = S->elem[S->top];
  return 1;
 }
 return 0;
}
//2.棧的鏈式結構
typedef struct node{
 int data;
 struct node *next;
}LinkStackNode, *LinkStack;
//a.初始化
void InitStack2(LinkStack top){
 top->next = NULL;
 top->data = 0;
}
//b.進棧
int Push2(LinkStackNode *top, int x)
/* 將數據元素 x 壓入棧 top 中 */
{
 LinkStackNode * temp;
 temp = (LinkStackNode *)malloc(sizeof(LinkStackNode));
 if (temp == NULL){
  return -1;   /* 申請空間失敗 */
 }
 else{
  temp->data = x;
  temp->next = top->next;
  top->next = temp;   /* 修改當前棧頂指針 */
  return 1;
 }
 return 0;
}
//c.出棧
int Pop2(LinkStack top, int *x) {  
 /* 將棧 top 的棧頂元素彈出,放到 x 所指的存儲空間中 */ 
 LinkStackNode * temp; 
 temp = top->next; 
 if (temp == NULL){  /*棧爲空*/
  return -1;
 }
 else{
  top->next = temp->next;
  *x = temp->data; free(temp);   /* 釋放存儲空間 */
  return *x;
 }
 return 0;
}
//3.隊列的順序存儲
#define MAXSIZE 50  /*隊列的最大長度*/ 
typedef struct {
 int  element[MAXSIZE];  /* 隊列的元素空間*/
 int  front;  /*頭指針指示器*/
 int  rear;  /*尾指針指示器*/
}SeqQueue;
//a.初始化
void InitQueue1(SeqQueue *Q){  /* 將*Q 初始化爲一個空的循環隊列 */
 Q->front = Q->rear = 0;
}
//b.入隊
int EnterQueue1(SeqQueue *Q, int x)
{  /*將元素 x 入隊*/
 if ((Q->rear + 1) % MAXSIZE == Q->front){  /*隊列已經滿了*/
  return -1;
 }
 else{
  Q->element[Q->rear] = x;
  Q->rear = (Q->rear + 1) % MAXSIZE;  /* 重新設置隊尾指針 */
  return 1;
 }  /*操作成功*/
 return 0;
}
//c.出隊
int DeleteQueue1(SeqQueue *Q, int *x)
{ /*刪除隊列的隊頭元素,用 x 返回其值*/
 if (Q->front == Q->rear){  /*隊列爲空*/
  return -1;
 }
 else{
  *x = Q->element[Q->front];
  Q->front = (Q->front + 1) % MAXSIZE;  /*重新設置隊頭指針*/
  return *x;  /*操作成功*/
 }
 return 0;
}
//4.隊列的鏈式存儲
typedef struct Node
{
 int data;//數據域
 struct Node *next;//指針域
}LinkQueueNode;
typedef struct
{
 LinkQueueNode *front;//隊頭指針front
 LinkQueueNode *rear;//隊頭指針rear
}LinkQueue;
//a.初始化
int InitQueue2(LinkQueue *Q)
{
 Q->front = (LinkQueueNode *)malloc(sizeof(LinkQueueNode));
 if (Q->front != NULL)
 {
  Q->rear = Q->front;
  Q->front->next = NULL;
  return 1;
 }
 else
 {
  return -1;//溢出
 }
 return 0;
}
//b.入隊
int EnterQueue2(LinkQueue *Q,int x)
{
 LinkQueueNode *NewNode;
 NewNode = (LinkQueueNode *)malloc(sizeof(LinkQueueNode));
 if (NewNode != NULL)
 {
   NewNode->data = x;
   NewNode->next = NULL;
   Q->rear->next = NewNode;
   Q->rear = NewNode;
  return 1;
 }
 else
 {
  return -1;//溢出
 }
 return 0;
}
//c.出隊
int DeleteQueue2(LinkQueue *Q,int *x)
{
 LinkQueueNode *p;
 if (Q->front == Q->rear)
 {
  return -1;
 }
 else{
  p = Q->front->next;
  Q->front->next = p->next;//隊頭元素p出隊
  if (Q->rear == p)//如果隊中只有一個元素p,則p出隊後成爲空隊
  {
   Q->rear = Q->front;
  }
  *x = p->data;
  free(p);//釋放存儲空間
  return *x;
 }
 return 0;
}
void menu1(){
 printf("##############################\n");
 printf("###########棧與隊列###########\n");
 printf("########1.棧的順序存儲########\n");
 printf("########2.棧的鏈式存儲########\n");
 printf("######3.隊列的順序存儲########\n");
 printf("######4.隊列的鏈式存儲########\n");
 printf("############5.退出############\n");
 printf("please enter your choice#");
}
void menu2()
{
 printf("#########################\n");
 printf("#########相關操作########\n");
 printf("##########1.入隊#########\n");
 printf("##########2.出隊#########\n");
 printf("##########3.退出#########\n");
 printf("#########################\n");
 printf("please enter your choice#");
}
void menu3(){
 printf("#########################\n");
 printf("#########相關操作########\n");
 printf("##########1.入棧#########\n");
 printf("##########2.出棧#########\n");
 printf("##########3.退出#########\n");
 printf("#########################\n");
 printf("please enter your choice#");
}
int main()
{
 int data;                       //輸入數據
 int data1;                      //輸出數據
 LinkQueue st1;                  //隊列鏈式存儲的結構體變量
 SeqQueue st2;                   //隊列順序存儲的結構體變量
 LinkStackNode st3;              //棧的鏈式存儲的結構體變量
 SeqStack st4;                   //棧的順序存儲的結構體變量
 int i = 1;
 int j = 1;
 while (i){
  menu1();
  int choice1 = 0;
  int choice2 = 0;
  scanf("%d", &choice1);
  switch (choice1){
  case 1:
   j = 1;
   InitStack1(&st4);
   while (j){
    menu3();
    scanf("%d", &choice2);
    switch (choice2){
    case 1:
     printf("請輸入整型,0表示輸入結束\n");
     printf("please enter your data: ");
     scanf("%d", &data);
     while (data != 0){
      Push1(&st4, data);
      scanf("%d", &data);
     }
     break;
    case 2:
     printf("Linked Storage outgoing queue is: ");
     while (st4.top!=-1){
      printf("%d", Pop1(&st4, &data1));
     }
     printf("\n");
     break;
    case 3:
     j = 0;
     break;
    default:
     printf("輸入錯誤,請重新輸入!\n");
     break;
    }
   }
   break;
  case 2:
   j = 1;
   InitStack2(&st3);
   while (j){
    menu3();
    scanf("%d", &choice2);
    switch (choice2){
    case 1:
     printf("請輸入整型,0表示輸入結束\n");
     printf("please enter your data: ");
     scanf("%d", &data);
     while (data != 0){
      Push2(&st3, data);
      scanf("%d", &data);
     }
     break;
    case 2:
     printf("Linked Storage outgoing queue is: ");
     while (st3.next!=NULL){
      printf("%d", Pop2(&st3, &data1));
     }
     printf("\n");
     break;
    case 3:
     j = 0;
     break;
    default:
     printf("輸入錯誤,請重新輸入!\n");
     break;
    }
   }
   break;
  case 3:
   j = 1;
   InitQueue1(&st2);
   while (j){
    menu2();
    scanf("%d", &choice2);
    switch (choice2){
    case 1:
     printf("請輸入整型,0表示輸入結束\n");
     printf("please enter your data: ");
     scanf("%d", &data);
     while (data != 0){
      EnterQueue1(&st2, data);
      scanf("%d", &data);
     }
     break;
    case 2:
     printf("Linked Storage outgoing queue is: ");
     while (st2.rear!=st2.front){
      printf("%d", DeleteQueue1(&st2, &data1));
     }
     printf("\n");
     break;
    case 3:
     j = 0;
     break;
    default:
     printf("輸入錯誤,請重新輸入!\n");
     break;
    }
   }
    break;
  case 4:
   j = 1;
   InitQueue2(&st1);
   while (j){
    menu2();
    scanf("%d", &choice2);
    switch (choice2){
    case 1:
     printf("請輸入整型,0表示輸入結束\n");
     printf("please enter your data: ");
     scanf("%d", &data);
     while (data != 0){
      EnterQueue2(&st1, data);
      scanf("%d", &data);
     }
     break;
    case 2:
     printf("Linked Storage outgoing queue is: ");
     while (st1.rear != st1.front){
      printf("%d", DeleteQueue2(&st1, &data1));
     }
     printf("\n");
     break;
    case 3:
     j = 0;
     break;
    default:
     printf("輸入錯誤,請重新輸入!\n");
     break;
    }
   }
   break;
  case 5:
   i = 0;
   break;
  default:
   printf("輸入錯誤,請重新輸入!\n");
   break;
   }
  }
 system("pause");
 return 0;
 }

關於隊列以及棧的相關操作在相關書籍上都會有,這裏去模擬棧與隊列,是讓更多的人去理解棧和隊列。
本次實驗代碼僅供參考(因爲在菜單的美觀性以及代碼本身的效率方面有待提高),所以大家在採納的過程中可以去在不同方面優化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章