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