您好,登錄后才能下訂單哦!
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#define N 3
typedef struct node
{
char name[20];
struct node *link;
}stud;
給node起“外號”使其命名為stud。
stud * creat(int n) /*建立單鏈表的函數*/
{
stud *p,*h,*s; //定義3個指針,其中*h為頭指針
inti;
if((h=(stud *)malloc(sizeof(stud)))==NULL) //如果*h的動態分配中stud的內存為空則不能分配。所取得都是地址。
{
printf("不能分配內存空間!");
exit(0);
}
h->name[0]='\0'; //把頭指針name中的地址放干,也就是為0
h->link=NULL; //把頭指針的第一項地址放空。頭指針只有link這一項
p=h; //h的地址賦給p,這里指針所蘊含的是地址。指針與指針之間交換的都是地址。
for(i=0;i<N;i++)
{
if((s= (stud *) malloc(sizeof(stud)))==NULL)//如果指針s的動態分配在stud中是空則顯示不能分配
{
printf("不能分配內存空間!");
exit(0);
}
p->link=s; //p的指針地址提前向s申請分配,把s的name給p。s的下一個指針地址要永遠為空,保證是最后一個。而且一定要讓p->link得到s所有的數據。
printf("請輸入第%d個人的姓名:",i+1);
scanf("%s",s->name);
s->link=NULL;
p=s;
}
return(h); //返回頭指針
}
stud * search(stud *h,char *x) /*查找函數*/
{
stud *p;
char *y;
p=h->link; //p獲得頭指針的下一個指針當p不為空時,p取得的name賦給y,然后讓y和x比較,如果x和y的值相同也就是等于0.就證明找到了,否則就讓p得到它的下一個指針數。再次重復,讓y獲得p的地址中name的地址。如果最后還是沒有的話,說明并沒有這個數據,顯示沒有。
while(p!=NULL)
{
y=p->name;
if(strcmp(y,x)==0)
return(p);
else p=p->link;
}
if(p==NULL)
printf("沒有查找到該數據!");
}
stud *search3(stud *h,char *x)
/*另一個查找函數,返回的是上一個查找函數的直接前驅結點的指針,
h為表頭指針,x為指向要查找的姓名的指針
其實此函數的算法與上面的查找算法是一樣的,只是多了一個指針s,并且s總是指向指針p所指向的結點的直接前驅,
結果返回s即是要查找的結點的前一個結點*/
{
stud *p,*s; //h 的link指針給p,h的值賦予給s當p不等于空時,y得到p地址的名字 ,兩者比較如果y和x相同說明找到了人,然后返還給s。s現在擔當為h。如果沒有找到p就得到向下一個地址,s也得到下一個地址。然后循環在進行比較。如果還是沒有也就是p的地址為空時,就說明沒有數據了。
表頭指針的link都屬于第一個項
而非表頭指針的link都屬于下一項
char *y;
p=h->link;
s=h;
while(p!=NULL)
{
y=p->name;
if(strcmp(y,x)==0)
return(s);
else
{
p=p->link;
s=s->link;
}
}
if(p==NULL)
printf("沒有查找到該數據!");
}
void insert(stud *p) /*插入函數,在指針p后插入*/
{
char stuname[20];
stud *s; /*指針s是保存新結點地址的*/
if((s= (stud *) malloc(sizeof(stud)))==NULL)//新定義的s指針的動態分配在stud中如果為空就表示不可分配空間顯示退出,如果不為空就證明有空間可以使用。設定stuname的值然后讓s獲取,在把p的下一個給s的下一個,然后s給p的下一個。
{
printf("不能分配內存空間!");
exit(0);
}
printf("請輸入你要插入的人的姓名:");
scanf("%s",stuname);
strcpy(s->name,stuname); /*把指針stuname所指向的數組元素拷貝給新結點的數據域*/
s->link=p->link; /*把新結點的鏈域指向原來p結點的后繼結點*/
p->link=s;/*p結點的鏈域指向新結點*/
}
// Y Z
X
中間想要插入X那么就要先讓Y的下一個指向給X的下一個指向。這樣X的下一個就指向了Z,在把X自己給Y的下一個,這樣就完成了插入。
void del(stud *x,stud *y) /*刪除函數,其中y為要刪除的結點的指針,x為要刪除的結點的前一個結點的指針*/
{
stud*s;
s=y;
x->link=y->link; // y的后一個指針賦予給x的后一個,相當于 X Y Z這么個關系,Y要被刪掉,那么它的下一個指向Z就賦予給了X的下一個,這樣的話,X的下一個就是Z了, Y就沒有用了。在清除掉S就算完成了刪除任務。
free(s);
}
void print(stud *h)
{
stud *p;
p=h->link; //表頭指針的link算是h的第一項給了P,這樣p就有了h 的第一個地址。
printf("數據信息為:\n");
while(p!=NULL)
{
printf("%s \n",&*(p->name));
p=p->link;
}
}
void quit()
{
exit(0);
}
void menu(void)
{
system("cls");
printf("\t\t\t單鏈表C語言實現實例\n");
printf("\t\t|----------------|\n");
printf("\t\t| |\n");
printf("\t\t| [1] 建 立 新 表 |\n");
printf("\t\t| [2] 查 找 數 據 |\n");
printf("\t\t| [3] 插 入 數 據 |\n");
printf("\t\t| [4] 刪 除 數 據 |\n");
printf("\t\t|[5] 打 印 數 據 |\n");
printf("\t\t| [6] 退 出 |\n");
printf("\t\t| |\n");
printf("\t\t| 如未建立新表,請先建立! |\n");
printf("\t\t| |\n");
printf("\t\t|----------------|\n");
printf("\t\t 請輸入你的選項(1-6):");
}
main()
{
int choose;
stud *head,*searchpoint,*forepoint;
char fullname[20];
while(1)
{
menu();
scanf("%d",&choose);
switch(choose)
{
case 1:
head=creat(N);
break;
case 2:
printf("輸入你所要查找的人的姓名:");
scanf("%s",fullname);
searchpoint=search(head,fullname);
printf("你所查找的人的姓名為:%s",*&searchpoint->name);
printf("\n按回車鍵回到主菜單。");
getchar();getchar();
break;
case 3: printf("輸入你要在哪個人后面插入:");
scanf("%s",fullname);
searchpoint=search(head,fullname);
printf("你所查找的人的姓名為:%s",*&searchpoint->name);
insert(searchpoint);
print(head);
printf("\n按回車鍵回到主菜單。");
getchar();getchar();
break;
case 4:
print(head);
printf("\n輸入你所要刪除的人的姓名:");
scanf("%s",fullname);
searchpoint=search(head,fullname);
forepoint=search3(head,fullname);
del(forepoint,searchpoint);
break;
case 5:
print(head);
printf("\n按回車鍵回到主菜單。");
getchar();getchar();
break;
case 6:quit();
break;
default:
printf("你輸入了非法字符!按回車鍵回到主菜單。");
system("cls");
menu();
getchar();
}
}
}
最后運用了“選擇” ,while(1)死循環,getchar();getchar()如果沒有getchar()阻止,那么界面就會無限刷新,因為while(1)是個死循環。保持界面一直在。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。