大連海事大學網路工程專業資料結構實驗程式碼
阿新 • • 發佈:2021-01-14
大連海事大學網路工程專業資料結構實驗程式碼
寫程式碼是一個非常重要的鍛鍊自己的過程,希望大家一定要自己寫,不要抄襲,並且注重資料結構與演算法的學習,希望我們海大的計算機系同學們都有一個光明的未來。
上程式碼了。
第一個實驗:多項式
/*
@lizzy_0323
翻版必究
TODO:
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
const double eps = 1e-8;
#define N 50
#define value(a,b) ((fabs((a) - (b)))<(eps))
typedef struct H{
double coef;
double expn;
struct H *next;
}HLink;
static int Is0 = 0;
//用於建立連結串列
void Build(HLink *H)
{
int i = 0;
char a;
//用於讀取錯誤輸入
char wrong[100];
HLink *p,*pend = NULL;
while(a != '#')
{
if((p = (HLink *)malloc(sizeof(HLink))) == NULL)
{
printf("記憶體分配失敗!");
exit(0);
}
if(H->next == NULL)
{
H->next = p;
pend = p;
}
else
{
pend->next = p;
pend = p;
}
printf ("請輸入第%d項的次數:", i + 1);
while(!(scanf("%lf", &p->expn)))
{
fgets(wrong,N,stdin);
printf("請以正確的格式錄入");
}
fgets(wrong,N,stdin);
printf("請輸入第%d項的係數為:",i + 1);
while(!(scanf("%lf", &p->coef)))
{
fgets(wrong,N,stdin);
printf("請以正確的格式錄入");
}
fgets(wrong,N,stdin);
printf("是否還要繼續輸入?(#號結束)");
a = getchar(); //讀取使用者輸入
fgets(wrong,N,stdin);
i++;
}
p->next = NULL;
}
//節點形式輸出
void OutOnenode(HLink *H)
{
HLink *p = NULL;
if(H->next == NULL)
{
if(Is0 == 0)
{
printf("當前多項式為空");
}
else
{
printf("次數為:0 係數為:0\n\n");
}
}
p = H->next;
while(p != NULL)
{
printf("次數為:%.2f,係數為:%.2f\n\n",p->expn, p->coef);
p = p->next;
}
}
//以多項式格式輸出
void Output(HLink *H)
{
HLink *p = NULL;
if(H->next == NULL)
{
if(Is0 == 0)
{
printf("當前多項式為空!");
}
else
{
printf("0");
}
return;
}
p = H->next;
if(value(p->expn,1))
{
if(value(p->coef,1))
{
printf("x");
}
else if(value(p->coef,-1))
{
printf("-x");
}
else
{
printf("%.2fx",p->coef);
}
}
else if(value(p->expn,0))
{
printf("%.2f",p->coef);
}
else
{
if(value(p->coef,1))
{
printf("x^%.2f",p->expn);
}
else if(value(p->coef,-1))
{
printf("-x^%.2f",p->expn);
}
else
{
printf("%.2fx^%.2f",p->coef, p->expn);
}
}
p = p->next;
while(p != NULL)
{
if(p->coef > 0)
{
printf("+");
if(value(p->expn,1))
{
if(value(p->coef,1))
{
printf("x");
}
else
{
printf("%.2fx",p->coef);
}
}
else if(value(p->expn,0))
{
printf("%.2f",p->coef);
}
else
{
if(value(p->coef,1))
{
printf("x^%.2f",p->expn);
}
else
{
printf("%.2fx^%.2f",p->coef,p->expn);
}
}
}
else //如果係數為小於0
{
printf("-");
if(value(p->expn,1))
{
if(value(p->coef,-1))
{
printf("x");
}
else
{
printf("%.2fx",(-(p->coef)));
}
}
else if(value(p->expn,0))
{
printf("%.2f",(-(p->coef)));
}
else
{
if(value(p->coef,-1))
{
printf("x^%.2f",p->expn);
}
else
{
printf("%.2fx^%.2f",(-(p->coef)), p->expn);
}
}
}
p = p->next;
}
}
//相加函式
void AddNode(HLink *H,HLink H1,HLink H2)
{
HLink *p,*q,*temp,*pend = NULL;
if(H1.next == NULL && H2.next == NULL)
{
return;
}
p = H1.next;
q = H2.next;
while(p && q)
{
//為臨時節點分配記憶體
if((temp = (HLink *)malloc(sizeof(HLink))) == NULL)
{
printf("記憶體分配失敗!");
exit(0);
}
//如果當前節點為空
if(H->next == NULL)
{
H->next = temp;
pend = temp;
}
if(p->expn > q->expn)
{
*temp = *p;
p = p->next;
}
else if(p->expn == q->expn)
{
*temp = *p;
temp->coef = p->coef + q->coef;
p = p->next;
q = q->next;
}
else
{
*temp = *q;
q = q->next;
}
pend->next = temp;
pend = temp;
}
while(p)
{
if((temp = (HLink *)malloc(sizeof(HLink))) == NULL)
{
printf("記憶體分配失敗!");
exit(0);
}
*temp= *p;
if(H->next == NULL)
{
H->next =temp;
}
else
{
pend->next = temp;
}
pend = temp;
p = p->next;
}
while(q)
{
if((temp = (HLink *)malloc(sizeof(HLink))) == NULL)
{
printf("記憶體分配失敗!");
exit(0);
}
*temp = *q;
if(H->next == NULL)
{
H->next = temp;
}
else
{
pend->next = temp;
}
pend = temp;
q = q->next;
}
temp->next = NULL;
}
//相乘函式
void MultH(HLink *H,HLink H1,HLink H2)
{
HLink *p,*q,*r,*pend = NULL;
q = H1.next;
//如果有空節點,直接返回
if(H1.next == NULL || H2.next == NULL)
{
return;
}
while(q)
{
r = H2.next;
while(r)
{
if((p = (HLink *)malloc(sizeof(HLink))) == NULL)
{
printf("記憶體分配失敗!");
exit(0);
}
if(H->next == NULL)
{
H->next = p;
pend = p;
}
else
{
pend->next = p;
pend = p;
}
p->expn = r->expn + q->expn;
p->coef = (r->coef) * (q->coef);
r = r->next;
}
q = q->next;
}
p->next = NULL;
}
//合併函式
void Union(HLink *H)
{
HLink *now,*pend,*p = NULL;
if(H->next == NULL)
{
return;
}
now = H->next;
pend = now->next;
while(pend)
{
if(now->expn == pend->expn)
{
now->coef += pend->coef;
p = pend;
pend = pend->next;
now->next = pend;
free(p);
}
else
{
now = now->next;
pend = pend->next;
}
}
}
//多項式排序函式
void Swap(HLink *H)
{
HLink *pre, *p, *pend,*phead=H->next;
//如果當前多項式為空
if(H->next == NULL)
{
return;
}
p=phead->next;
phead->next = NULL;
//當前節點不為空
while(p != NULL)
{
pend = p->next;
pre = H;
while(pre->next != NULL && ((pre->next->expn) > (p->expn)))
{
pre = pre->next;
}
p->next = pre->next;
pre->next = p;
p = pend;
}
}
//檢查是否有清零的函式
void Check0(HLink *H)
{
HLink *pre,*p,*pend = NULL;
pre = H;
p = H->next;
while(p != NULL)
{
if(p->coef == 0)
{
pre->next = p->next;
pend = p;
p = p->next;
free(pend);
Is0 = 1;
}
else
{
p = p->next;
pre = pre->next;
}
}
}
//清除多項式函式
void Check(HLink *H)
{
HLink *p,*pend = NULL;
p = H->next;
while(p)
{
pend = p;
p = p->next;
free(pend);
}
H->next = NULL;
}
//用於顯示選單
void Menu()
{
printf("請輸入序號選擇功能:\n");
printf("1、錄入新的多項式\n");
printf("2、顯示多項式各項次數為和對應係數\n");
printf("3、輸出多項式表示式\n");
printf("4、多項式加法\n");
printf("5、多項式乘法\n");
printf("0、退出\n");
}
//主函式
int main()
{
int button;
int j = 0;
double expn;
char pend[100];
int index[100] = {0};
//指標陣列
HLink *pt[100] = {NULL};
HLink *H1,*H2,*q,*r,*e = NULL;
//對指標進行初始化
H1 = (HLink *)malloc(sizeof(HLink));
H1->next = NULL;
H2 = (HLink *)malloc(sizeof(HLink));
H2->next = NULL;
q = (HLink *)malloc(sizeof(HLink));
q->next = NULL;
e = (HLink *)malloc(sizeof(HLink));
e->next = NULL;
while(1)
{
//列印選單
Menu();
scanf("%d", &button);
switch(button)
{
case 1:
{
char a;
for(int index = 0;index < j;index++)
{
Check(pt[index]);
}
j = 0;
//讀取使用者輸入
do
{
if((pt[j] = (HLink *)malloc(sizeof(HLink))) == NULL)
{
printf("記憶體分配失敗!"); //如果分配失敗
exit(0);
}
pt[j]->next = NULL;
printf("當前為第%d個多項式\n",j + 1);
Build(pt[j]);
Check0(pt[j]);
Swap(pt[j]);
Union(pt[j]);
j++;
printf("是否還要繼續錄入?(#號結束)");
a = getchar();
fgets(pend,N,stdin);
} while(a != '#'); //輸入#時結束
printf("\n");
break;
}
case 2:
{
if(j == 0 && H1->next == NULL && H2->next ==NULL)
{
printf("沒有錄入任何資料!\n");
}
else
{
for(int k = 0;k < j;k++)
{
printf("----當前為第%d個多項式--------\n",k+1);
OutOnenode(pt[k]);
}
if(H1->next != NULL)
{
printf("--------多項式1為--------\n");
OutOnenode(H1);
}
if(H2->next != NULL)
{
printf("--------多項式2為--------\n");
OutOnenode(H2);
}
}
break;
}
case 3:
{
if(j == 0 && H1->next == NULL && H2->next ==NULL)
{
printf("沒有錄入任何資料!\n");
}
else
{
for(int k = 0;k < j;k++)
{
printf("-----第%d個多項式--------\n",k+1);
Output(pt[k]);
}
if(H1->next != NULL)
{
printf("--------多項式1為--------\n");
Output(H1);
}
if(H2->next != NULL)
{
printf("--------多項式2為--------\n");
Output(H2);
}
}
break;
}
case 4:
{
if(j == 0)
{
printf("當前無多項式錄入!\n");
break;
}
printf("當前共有%d個多項式\n",j);
int k;
for(k = 0;k < j;k++)
{
printf("第%d個多項式:",k + 1);
Output(pt[k]);
printf("\n");
}
printf("請輸入需要相加的多項式序號,輸入0後結束:");
k = 0;
Check(q);
while(index[k] != 0)
{
if(k % 2 == 0)
{
Check(H1);
AddNode(H1,*q,*pt[index[k] - 1]);
Check0(H1);
}
else
{
Check(q);
AddNode(q,*H1,*pt[index[k] - 1]);
Check0(q);
}
k++;
}
if(k % 2 == 0)
{
Check(H1);
H1->next = q->next;
}
else
{
Check(q);
}
printf("--------相加後的多項式為--------\n");
Output(H1);
break;
}
case 5:
{
int k = 0;
if(j == 0)
{
printf("當前無多項式錄入!\n");
break;
}
printf("當前共有%d個多項式",j);
for(k = 0;k < j;k++)
{
printf("第%d個多項式:",k + 1);
Output(pt[k]);
printf("\n");
}
printf("請輸入需要相乘的多項式序號,(輸入0後結束輸入):");
k = 0;
if(index[0] == 0)
{
printf("當前沒有選擇多項式\n");
break;
}
Check(e);
if((r = (HLink *)malloc(sizeof(HLink))) == NULL)
{
printf("記憶體分配失敗!");
exit(0);
}
r->expn = 0;
r->coef = 1;
e->next = r;
r->next = NULL;
k = 0;
while(index[k] != 0)
{
if(k % 2 == 0)
{
Check(H2);
MultH(H2,*e,*pt[index[k] - 1]);
Swap(H2);
Union(H2);
}
else
{
Check(e);
MultH(e,*H2,*pt[index[k] - 1]);
Swap(e);
Union(e);
}
k++;
}
if(k % 2 == 0)
{
Check(H2);
H2->next = e->next;
}
else
{
Check(e);
}
printf("-------相乘後的多項式為--------\n");
Output(H2);
break;
}
case 0:
{
printf("程式已安全退出\n");
exit(0);
break;
}
default:
{
printf("輸入錯誤,請重新輸入!\n\n");
break;
}
}
}
return 0;
}
第二個實驗:字串匹配演算法:
/*
@lizzy_0323
FOR
Real
翻版必究
TODO:
*/
#include <cstdlib>
#include<stdio.h>
#include<string.h>
#define N 50
char wrong[N];//用於儲存錯誤輸入
char c1[N][N], c2[N][N];//用於儲存兩個字串
void Out()
{
printf("請問您是否要現在退出程式?\n");
printf("1-是 2-不是\n");
int t;//用於判斷使用者當前是否要進行退出
scanf("%d",&t);
if(t==1)
{
printf("程式已安全退出\n");
exit(0);
}
else
{
return;
}
}
void Menu()
{
printf("*****************************\n");
printf("1.輸入主串,子串和匹配起始位置\n");
printf("2.樸素的模式匹配演算法\n");
printf("3.KMP演算法(Next[])\n");
printf("4.KMP演算法(Nextval[])\n");
printf("5.修改主串或者子串\n");
printf("6-刪除字串\n");
printf("0.退出管理系統\n");
printf("*****************************\n");
}
void getString2(int c)
{
fgets(c2[c],20,stdin);
int i=strlen(c2[c]);
if(c2[c][i-1]=='\n') //因為最後一行沒有回車符
{
c2[c][i-1]='\0';
}
}
void getString1(int c)
{
fgets(c1[c],20,stdin);
int i=strlen(c2[c]);
if(c1[c][i-1]=='\n') //因為最後一行沒有回車符
{
c1[c][i-1]='\0';
}
}
//樸素的模式匹配演算法
int BF(char* a, char* b, int pos)
{
int length1, length2;
length1 = strlen(a)-1;
length2 = strlen(b)-1;
int i = pos, j = 0, k = 0;
int count = 1;//記錄比較次數
bool is1 = true;
bool isIn=true;
int num[N];
for (i = 0; i <= length2; i++)//先為num陣列賦0
{
num[i] = 0;
}
i = 0;
printf("當前主串是%s\n", a);
printf("當前子串是%s\n", b);
while (i <= length1 && j <= length2 )//如果匹配沒到末尾
{
if (count == 1 && is1 == true)
{
printf("當前為第%d趟\n", count);
}
num[j] += 1;
if (a[i] == b[j])//如果當前字元匹配相同,繼續匹配後續字元
{
printf("%c,%c\n", a[i], b[j]);
i++;
j++;
is1 = false;
isIn=true;
}
else
{
printf("%c,%c\n", a[i], b[j]);
i = i - j + 1;
j = 0;//回到初始位置
isIn=false;
if(a[i]!='\0'&&a[i]!='\n')
{
count++;
printf("當前為第%d趟\n", count);
}
//printf("當前為第%d趟\n", count);
}
}
printf("匹配結束\n");
for (k = 0; k <= length2; k++)//先為num陣列賦0
{
printf("模式串第%d個字元匹配的次數是%d\n", k+1, num[k]);
}
if (j >= length2&&isIn==true)//匹配成功
{
printf("匹配總趟數是%d\n", count);
return i - length2;//返回匹配成功的位置
}
else
{
printf("匹配總趟數是%d\n", count);
return 0;
}
}
//獲取next陣列
void Get_next(char* b, int* next)
{
int j = 0, k = -1;
next[j] = k;
int length = strlen(b)-1;
while (j <= length)
{
if (k == -1 || b[j] == b[k])//如果回到了第一個字元或匹配成功
{
j++;
k++;
next[j] = k;
}
else//如果匹配失敗
{
k = next[k];
}
}
return;
}
//獲取nextval陣列
void Get_nextval(char* b, int* nextval)
{
int j = 0, k = -1;
nextval[j] = k;
int length = strlen(b)-1;
while (j<=length)
{
if (k == -1 || b[j] == b[k])//如果回到了第一個字元或匹配成功
{
j++;
k++;
if (b[j] != b[k])
{
nextval[j] = k;
}
else
{
nextval[j] = nextval[k];
}
}
else//如果匹配失敗
{
k = nextval[k];
}
}
return;
}
//KMP演算法
int KMP(char* a, char* b, int pos)
{
int length1, length2;
length1 = strlen(a)-1;
length2 = strlen(b)-1;
int i = pos, j = 0, k = 0;
int next[N];//定義一個next陣列
int num[N];
bool is1 = true;
bool isIn=true;
printf("當前主串是%s\n", a);
printf("當前子串是%s\n", b);
Get_next(b, next);
int count = 1;//記錄比較次數
for (i = 0; i <=length2; i++)//先為num陣列賦0
{
num[i] = 0;
}
i = 0;
while (i <= length1 && j <= length2 )//如果匹配沒到末尾
{
if (count == 1 && is1 == true)
{
printf("當前為第%d趟\n", count);
}
if (j == -1 || a[i] == b[j])//如果當前字元匹配相同或第一位就不同,繼續匹配後續字元
{
if (j != -1)
{
num[j] += 1;
printf("%c,%c\n", a[i], b[j]);
}
else
{
num[0] += 1;
}
i++;
j++;
is1 = false;
isIn=true;
}
else
{
printf("%c,%c\n", a[i], b[j]);
j = next[j];//回到陣列指向的位置
isIn=false;
if(a[i]!='\0'&&a[i]!='\n')
{
count++;
printf("當前為第%d趟\n", count);
}
}
}
printf("匹配結束\n");
for (k = 0; k <=length2; k++)
{
printf("模式串第%d個字元匹配的次數是%d\n", k+1, num[k]);
}
if (j >= length2&&isIn==true)//匹配成功
{
printf("匹配總趟數是%d\n", count);
return i - length2;//返回匹配成功的位置
}
else
{
printf("匹配總趟數是%d\n", count);
return 0;
}
}
//改進的KMP演算法
int KMP_Nextval(char* a, char* b, int pos)
{
int length1, length2;
length1 = strlen(a) - 1;
length2 = strlen(b) - 1;
int i = pos, j = 0, k = 0;
int nextval[N];//定義一個next陣列
int num[N];
bool isIn=true;
bool is1 = true;
printf("當前主串是%s\n", a);
printf("當前子串是%s\n", b);
Get_nextval(b, nextval);
int count = 1;//記錄比較次數
for (i = 0; i <= length2; i++)//先為num陣列賦0
{
num[i] = 0;
}
i = 0;
while (i <= length1 && j <= length2)//如果匹配沒到末尾
{
if (count == 1 && is1 == true)
{
printf("當前為第%d趟\n", count);
}
if (j == -1 || a[i] == b[j])//如果當前字元匹配相同或第一位就不同,繼續匹配後續字元
{
if (j != -1)
{
num[j] += 1;
printf("%c,%c\n", a[i], b[j]);
}
else
{
num[0] += 1;
}
i++;
j++;
is1 = false;
isIn=true;
}
else
{
printf("%c,%c\n", a[i], b[j]);
j = nextval[j];//回到陣列指向的位置
isIn=false;
if(a[i]!='\0'&&a[i]!='\n')
{
count++;
printf("當前為第%d趟\n", count);
}
}
}
printf("匹配結束\n");
for (k = 0; k <= length2; k++)//先為num陣列賦0
{
printf("模式串第%d個字元匹配的次數是%d\n", k + 1, num[k]);
}
if (j >= length2&&isIn==true)//匹配成功
{
printf("匹配總趟數是%d\n", count);
return i - length2;//返回匹配成功的位置
}
else
{
printf("匹配總趟數是%d\n", count);
return 0;
}
}
//用於刪除字串
void Delete()
{
int button;
printf("請輸入要刪除的字串型別\n");
printf("1-主串 2-子串\n");
while (scanf("%d", &button) != 1)
{
fgets(wrong,20,stdin);
printf("輸入不合法,請重新輸入\n");
}
//如果刪除主串
if(button==1)
{
printf("請輸入要刪除的主串位置\n");
while (scanf("%d", &button) != 1)
{
fgets(wrong,20,stdin);
printf("輸入不合法,請重新輸入\n");
}
c1[button][0]='\0';
}
//如果刪除子串
if(button==2)
{
printf("請輸入要刪除的子串位置\n");
while (scanf("%d", &button) != 1)
{
fgets(wrong,20,stdin);
printf("輸入不合法,請重新輸入\n");
}
c2[button][0]='\0';
}
}
int main()
{
//顯示使用者選單
int button;
int index = 1;//用於儲存匹配起始位置
int ans1=0, ans2=0, ans3=0;
int a = 0;
int x = 0;
while (a < 100)//繼續迴圈的條件
{
Menu();
while (scanf("%d", &button) != 1)
{
fgets(wrong,20,stdin);
printf("輸入不合法,請重新輸入\n");
}
switch (button)
{
case(0):
printf("管理系統已退出!\n");
a = 100;
break;
case(1):
printf("請輸入要儲存的位置(1-100)\n");
while (scanf("%d", &x) != 1)
{
fgets(wrong,20,stdin);
printf("輸入不合法,請重新輸入\n");
}
getchar();
printf("請輸入主串\n");
getString1(x);
printf("請輸入子串\n");
getString2(x);
while (strlen(c1[x]) < strlen(c2[x]))//如果子串長度大於主串
{
printf("子串長度大於主串,請重新輸入正確的子串和主串\n");
printf("請輸入主串\n");
scanf("%s", c1[x], 100);
printf("請輸入子串\n");
getString2(x);
}
printf("請輸入匹配起始位置\n");
while ((scanf("%d", &index) != 1))//如果輸入錯誤或者匹配位置大於主串位置
{
printf("請輸入正確的起始位置\n");
fgets(wrong,20,stdin);
}
if(index>strlen(c1[x]))
{
printf("匹配位置大於主串長度請輸入正確的起始位置\n");
while ((scanf("%d", &index) != 1))//如果輸入錯誤或者匹配位置大於主串位置
{
printf("請輸入正確的起始位置\n");
fgets(wrong,20,stdin);
}
}
Out();
break;
case(2):
printf("請輸入要進行匹配字串的位置(1-100)\n");
while (scanf("%d", &x) != 1)
{
fgets(wrong,20,stdin);
printf("輸入不合法,請重新輸入\n");
}
while (strlen(c1[x])>N)
{
printf("您輸入的位置當前無字串儲存\n");
printf("請重新輸入要進行匹配的位置(1-100)\n");
while (scanf("%d", &x) != 1)
{
fgets(wrong,20,stdin);
printf("輸入不合法,請重新輸入\n");
}
}
ans1 = BF(c1[x], c2[x], index - 1);
if (ans1 == 0)
{
printf("匹配失敗\n");
}
else
{
printf("匹配成功,成功的位置序號是%d\n", ans1);
}
Out();
break;
case(3):
printf("請輸入要進行匹配的位置(1-100)\n");
while (scanf("%d", &x) != 1)
{
fgets(wrong,20,stdin);
printf("輸入不合法,請重新輸入\n");
}
if (strlen(c1[x]) >= 1)//如果有字元
{
ans2 = KMP(c1[x], c2[x], index - 1);
}
else
{
printf("您輸入的位置當前無字串儲存\n");
break;
}
if (ans2 == 0)
{
printf("匹配失敗\n");
}
else
{
printf("匹配成功,成功的位置序號是%d\n", ans2);
}
Out();
break;
case(4):
printf("請輸入要進行匹配的位置(1-100)\n");
while (scanf("%d", &x) != 1)
{
fgets(wrong,20,stdin);
printf("輸入不合法,請重新輸入\n");
}
if (strlen(c1[x]) >= 1)//如果有字元,進行匹配
{
ans3 = KMP_Nextval(c1[x], c2[x], index - 1);
}
else
{
printf("您輸入的位置當前無字串儲存\n");
break;
}
if (ans3 == 0)
{
printf("匹配失敗\n");
}
else
{
printf("匹配成功,成功的位置序號是%d\n", ans3);
}
Out();
break;
case(5):
{
printf("請輸入要修改的串型別\n");
printf("1-主串,2-子串\n");
int b,c;
while (scanf("%d", &b) != 1)
{
fgets(wrong,20,stdin);
printf("輸入不合法,請重新輸入\n");
}
if(b==1)
{
printf("請輸入要修改的主串位置\n");
while (scanf("%d", &c) != 1)
{
fgets(wrong,20,stdin);
printf("輸入不合法,請重新輸入\n");
}
printf("請輸入修改後的字串\n");
getchar();
getString1(c);
break;
}
if(b==2)
{
printf("請輸入要修改的子串位置\n");
while (scanf("%d", &c) != 1)
{
fgets(wrong,20,stdin);
printf("輸入不合法,請重新輸入\n");
}
printf("請輸入修改後的字串\n");
getchar();
getString2(c);
break;
}
else
{
printf("當前無修改操作\n");
}
Out();
break;
}
case(6):
{
Delete();
break;
}
default:
printf("無對應選項,請重新輸入\n");
break;
}
}
return 0;
}
第三個實驗:二叉樹
/*
@lizzy_0323
翻版必究
TODO:
*/
#include <iostream>
#include <stdlib.h>
#include<string.h>
#include<vector>
#define N 50
using namespace std;
int a[N];
//用於記錄是否有重複節點
int bp=1;
static int num1=0,num2=0,num3=0;//用於計算
//定義樹結構
struct TreeNode {
struct TreeNode * LeftNode;
string data;
struct TreeNode * RightNode;
};
//用於判斷輸入是否正確
int Judgeint(int x)
{
int i;
char wrong[N];
while (1)
{
if (scanf("%d", &i) == 0)
{
printf("輸入錯誤請 重新輸入 Error型別為 : %d\n", x);
fgets(wrong,N,stdin);
}
else
{
return i;
}
}
}
//用於顯示選單
void Menu()
{
printf("____________________________________________\n");
printf("| 1.建立二叉樹 |\n");
printf("| 2.新增節點 |\n");
printf("| 3.列印前序遍歷結果 |\n");
printf("| 4.列印中序遍歷結果 |\n");
printf("| 5.列印後序遍歷結果 |\n");
printf("| 6.列印層序遍歷結果 |\n");
printf("| 7.求根到給定節點的路徑 |\n");
printf("| 8.退出 |\n");
printf("|___________________________________________|\n");
return;
}
//新增節點
void AddNode(TreeNode ** tree, string value)
{
if (*tree == NULL)
{
//為指標節點分配一段地址
*tree = (TreeNode*)malloc(sizeof(TreeNode));
if (*tree != NULL)
{
(*tree)->LeftNode = NULL;
(*tree)->data=value;
(*tree)->RightNode = NULL;
}
else
{
printf("記憶體分配失敗\n");
}
}
else
{
if (value <= (*tree)->data)
AddNode(&((*tree)->LeftNode), value);
if (value > (*tree)->data)
AddNode(&((*tree)->RightNode), value);
}
}
//建立二叉樹
void CreatTree(TreeNode **Tree)
{
string x;
int num=0;
printf("請輸入該二叉樹的節點個數(1-20)\n");
num=Judgeint(1);
while(num>20)
{
printf("請重新輸入該二叉樹的節點個數(1-20)\n");
num=Judgeint(1);
}
*Tree=NULL;
for(int i=0;i<num;i++)
{
x.resize(N);
printf("請輸入節點\n");
scanf("%s",&x[0]);
AddNode(Tree, x);
}
printf("建立完成\n");
}
//先序遍歷
void FirPut(TreeNode * tree)
{
if (tree == NULL)
{
if(num1==0)
{
printf("該二叉樹沒有節點儲存\n");
}
return;
}
num1++;
printf("%s ", (tree->data).c_str());
FirPut(tree->LeftNode);
FirPut(tree->RightNode);
}
//中序遍歷
void SecPut(TreeNode * tree)
{
if (tree == NULL)
{
if(num2==0)
{
printf("該二叉樹沒有節點儲存\n");
}
return;
}
num2++;
SecPut(tree->LeftNode);
printf("%s ", (tree->data).c_str());
SecPut(tree->RightNode);
}
//後序遍歷
void ThrPut(TreeNode * tree)
{
if (tree == NULL)
{
if(num3==0)
{
printf("該二叉樹沒有節點儲存\n");
}
return;
}
num3++;
ThrPut(tree->LeftNode);
ThrPut(tree->RightNode);
printf("%s ", (tree->data).c_str());
}
//層序遍歷
void LevPut(TreeNode * tree)
{
//定義佇列結構
struct Queue
{
TreeNode * data;
struct Queue * Next;
};
Queue *phead, *pend, *pnew;
phead = (Queue*)malloc(sizeof(Queue));
phead->data = tree;
phead->Next = NULL;
pend = phead;
do
{
TreeNode * Temp = NULL;
Temp = phead->data;
//head = head->Next;
if (Temp->LeftNode != NULL)
{
//申請一個臨時節點
pnew = (Queue*)malloc(sizeof(Queue));
pnew->data = NULL;
pnew->Next = NULL;
pnew->data = Temp->LeftNode;
pend->Next = pnew;
pend = pend->Next;
}
if (Temp->RightNode != NULL)
{
pnew = (Queue*)malloc(sizeof(Queue));
pnew->data = NULL;
pnew->Next = NULL;
pnew->data = Temp->RightNode;
pend->Next = pnew;
pend = pend->Next;
}
printf("%s ", Temp->data.c_str());
//頭節點出隊
phead = phead->Next;
} while (phead != NULL);
}
//用於判斷是哪棵樹
int WhichTree()
{
printf("請輸入要進行操作的二叉樹位置(1-20)\n");
int index=Judgeint(1);
while(index>20)
{
printf("請重新輸入要進行操作的二叉樹位置(1-20)\n");
index=Judgeint(1);
}
return index;
}
//求根節點到該節點的路徑
bool ShowPath(TreeNode*tree,string value)
{
TreeNode * Node = tree;
int i=0;
while (Node != NULL && Node->data != value)
{
if (value < Node->data)
{
Node = Node->LeftNode;
a[i]=1;
}
else
{
Node = Node->RightNode;
a[i]=2;
}
i++;
}
if (Node == NULL)
return false;
//如果找到了節點
else
{
//用於統計重複節點的個數
while(Node!=NULL&&Node->LeftNode!=NULL&&Node->LeftNode->data==Node->data)
{
bp++;
Node=Node->LeftNode;
}
return true;
}
}
//主函式部分
int main()
{
TreeNode * tree[N]={NULL};//定義一個樹的陣列
int x;
int index;
while (1)
{
Menu();
switch (Judgeint(1))
{
case 1:
{
CreatTree(&tree[index=WhichTree()]);
break;
}
case 2:
{
string i;
index=WhichTree();
printf("請輸入要插入節點的值\n");
i=Judgeint(2);
AddNode(&tree[index], i);
break;
}
case 3:
{
printf("前序遍歷 :");
FirPut(tree[index=WhichTree()]);
printf("\n");
break;
}
case 4:
{
printf("中序遍歷 : ");
SecPut(tree[index=WhichTree()]);
printf("\n");
break;
}
case 5:
{
printf("後序遍歷 : ");
ThrPut(tree[index=WhichTree()]);
printf("\n");
break;
}
case 6:
{
printf("層序遍歷 : ");
LevPut(tree[index=WhichTree()]);
printf("\n");
break;
}
case 7:
{
int j=0;
string newData;
index=WhichTree();
printf("請輸入要查詢的節點所儲存的資料\n");
newData.resize(N);
scanf("%s",&newData[0]);
if(ShowPath(tree[index],newData))//如果查詢成功
{
int i1=1;
do
{
printf("以下為路徑%d\n",i1);
TreeNode *temptree=tree[index];
for(int i=0;a[i]!=0;i++)
{
cout<<" "<<temptree->data ;
if(a[i]==1)//如果指向左端
{
temptree=temptree->LeftNode;
}
if(a[i]==2)//如果指向右端
{
temptree=temptree->RightNode;
}
}
for(int k=i1;k<=bp;k++)
{
cout<<temptree->data<<endl;
}
printf("\n");
i1++;
} while (i1<=bp);
for(int i=0;a[i]!=0;i++)
{
a[i]=0;
}
break;
}
else
{
printf("未查詢到該節點\n");
}
break;
}
case 8:
{
printf("程式已安全退出\n");
exit(0);
break;
}
default:
printf("輸入錯誤 請重新輸入 \n");
break;
}
}
}