slnklist.h
#include <stdio.h> #include <stdlib.h> /**************************************/ /* 鏈表實現的頭文件,文件名slnklist.h */ /**************************************/ typedef int datatype; typedef struct link_node{ datatype info; struct link_node *next; }node; typedef node *linklist; /******************************************/ /*函數名稱:creatbystack() */ /*函數功能:頭插法建立帶頭結點的單鏈表 */ /******************************************/ linklist creatbystack() { linklist head,s; datatype x; head=(linklist)malloc(sizeof(node)); head->next=NULL; printf("請輸入整數序列(空格分開,以0結束):\n"); scanf("%d",&x); while (x!=0) { s=(linklist)malloc(sizeof(node)); s->info=x; s->next=head->next; head->next=s; scanf("%d",&x); } return head; } /***************************************/ /*函數名稱:creatbyqueue() */ /*函數功能:尾插法建立帶頭結點的單鏈表 */ /***************************************/ linklist creatbyqueue() { linklist head,r,s; datatype x; head=r=(linklist)malloc(sizeof(node)); head->next=NULL; printf("請輸入整數序列(空格分開,以0結束):\n"); scanf("%d",&x); while (x!=0) { s=(linklist)malloc(sizeof(node)); s->info=x; r->next=s; //把新元素放到當前元素后面 r=s; //把當前指針指向新元素 scanf("%d",&x); } r->next=NULL; return head; } /**********************************/ /*函數名稱:print() */ /*函數功能:輸出帶頭結點的單鏈表 */ /**********************************/ void print(linklist head) { linklist p; int i=0; p=head->next; printf("List is:\n"); while(p) { printf("%7d",p->info); i++; if (i%10==0) printf("\n"); p=p->next; } printf("\n"); } /******************************************/ /*函數名稱:creatLink() */ /*函數功能:從文件中讀入n個數據構成單鏈表 */ /******************************************/ linklist creatLink(char *f, int n) { FILE *fp; int i; linklist s,head,r; head=r=(linklist)malloc(sizeof(node)); head->next=NULL; fp=fopen(f,"r"); if (fp==NULL) return head; else { for (i=0;i<n;i++) { s=(linklist)malloc(sizeof(node)); fscanf(fp,"%d",&(s->info)); r->next=s; r=s; } r->next=NULL; fclose(fp); return head; } } /* 函數名稱:writetofile 函數功能:將鏈表內容存入文件f */ void writetofile(linklist head, char *f) { FILE *fp; linklist p; int i=0; fp=fopen(f,"w"); if (fp!=NULL) { p=head->next; fprintf(fp,"%s","List is:\n"); while(p) { fprintf(fp,"%7d",p->info); i++; if (i%10==0) fprintf(fp,"%c",'\n'); p=p->next; } fprintf(fp,"%c",'\n'); fclose(fp); } else printf("創建文件失敗!"); } /**********************************/ /*函數名稱:delList() */ /*函數功能:釋放帶頭結點的單鏈表 */ /**********************************/ void delList(linklist head) { linklist p=head; while (p) { head=p->next; free(p); p=head; } }
源文件
/*編寫函數void delx(linklist head, datatype x),刪除帶頭結點單鏈表head中第一個值為x 的結點。 並構造測試用例進行測試。 */ /**********************************/ /*文件名稱:lab3_01.c */ /**********************************/ #include "slnklist.h" /*請將本函數補充完整,並進行測試*/ linklist delx(linklist head,datatype x) { linklist p,pre=head; //別忘了pre=head p = head->next; while(p->info!=x) { pre = p; p = p->next; } if(p) { pre->next = p->next; free(p); } return head; } int main() { datatype x; linklist head; head=creatbyqueue(); /*尾插入法建立帶頭結點的單鏈表*/ print(head); printf("請輸入要刪除的值:"); scanf("%d",&x); head=delx(head,x); /*刪除單鏈表的第一個值為x的結點*/ print(head); delList(head); /*釋放單鏈表空間*/ return 0; }
/**********************************/ /*文件名稱:lab3_02.c */ /**********************************/ /* 假設線性表(a1,a2,a3,…an)采用帶頭結點的單鏈表存儲,請設計算法函數linklist reverse(linklist head), 將帶頭結點的單鏈表head就地倒置,使表變成(an,an-1,…a3.a2,a1)。並構造測試用例進行測試。 */ #include "slnklist.h" /*請將本函數補充完整,並進行測試*/ linklist reverse(linklist head) { //不帶頭節點是head,帶頭節點是head->next linklist p,q; p = head->next; head->next = NULL; while(p) { q = p->next; p->next = head->next; head->next = p; p = q; } return head; } int main() { datatype x; linklist head; head=creatbystack(); /*頭插入法建立帶頭結點的單鏈表*/ print(head); /*輸出原鏈表*/ head= reverse(head); /*倒置單鏈表*/ print(head); /*輸出倒置后的鏈表*/ delList(head); return 0; }
/* 假設帶頭結點的單鏈表head是升序排列的,設計算法函數linklist insert(linklist head,datatype x), 將值為x的結點插入到鏈表head中,並保持鏈表有序性。 分別構造插入到表頭、表中和表尾三種情況的測試用例進行測試。 */ /**********************************/ /*文件名稱:lab3_03.c */ /**********************************/ #include "slnklist.h" /*請將本函數補充完整,並進行測試*/ linklist insert(linklist head ,datatype x) { //要插入的數據s,位於pre和 p之間 linklist pre,p,s; s = (linklist)malloc(sizeof(node)); s->info = x; p = head->next; pre = head; while(p&&p->info<x) { pre = p; p = p->next; } pre->next = s; s->next = p; return head; } int main() { datatype x; linklist head; printf("輸入一組升序排列的整數:\n"); head=creatbyqueue(); /*尾插入法建立帶頭結點的單鏈表*/ print(head); printf("請輸入要插入的值:"); scanf("%d",&x); head=insert(head,x); /*將輸入的值插入到帶頭結點的單鏈表適當位置*/ print(head); delList(head); return 0; }
/* 編寫算法函數linklist delallx(linklist head, int x),刪除帶頭結點單鏈表head中所有值為x的結點。 */ /**********************************/ /*文件名稱:lab3_04.c */ /**********************************/ #include "slnklist.h" /*請將本函數補充完整,並進行測試*/ linklist delallx(linklist head,int x) { //不帶頭節點是head,帶頭節點是head->next linklist p,t; while(head->next)//如果要刪除的是第一個 { if(head->next->info==x)//如果第一個數=x { p=head->next;//刪除操作 head->next=head->next->next; free(p);//回收p } else { break; } } if(head->next)//如果刪除的不是第一個 { p=head->next; while(p->next) { if(p->next->info==x) { t=p->next; p->next=p->next->next; free(t); } else { p=p->next; } } } return head; } int main() { datatype x; linklist head; head=creatbyqueue(); /*尾插入法建立帶頭結點的單鏈表*/ print(head); printf("請輸入要刪除的值:"); scanf("%d",&x); head=delallx(head,x); print(head); delList(head); return 0; }
/* 已知線性表存儲在帶頭結點的單鏈表head中,請設計算法函數void sort(linklist head),將head中的結點按結點值升序排列。 */ /**********************************/ /*文件名稱:lab3_05.c */ /**********************************/ #include "slnklist.h" /*請將本函數補充完整,並進行測試*/ void sort(linklist head) { int temp; //temp是int類型,notice linklist p,pre; pre=p=head->next; while(pre) //pre是前面那個數,p是后面那個數 { p=pre;//notice,p是從pre后面數里走 while(p) { if(pre->info>p->info) //交換 { temp=p->info; p->info=pre->info; pre->info=temp; } p=p->next; } pre=pre->next; } return head; } int main() { linklist head; head=creatbyqueue(); /*尾插法建立帶頭結點的單鏈表*/ print(head); /*輸出單鏈表head*/ sort(head); /*排序*/ print(head); delList(head); return 0; }
/* 已知兩個帶頭結點的單鏈表L1和L2中的結點值均已按升序排序,設計算法函數 linklist mergeAscend (linklist L1,linklist L2)將L1和L2合並成一個升序的 帶頭結單鏈表作為函數的返回結果; 設計算法函數linklist mergeDescend (linklist L1,linklist L2) 將L1和L2合並成一個降序的帶頭結單鏈表作為函數的返回結果; 並設計main()函數進行測試。 */ /**********************************/ /*文件名稱:lab3_06.c */ /**********************************/ #include "slnklist.h" /*請將本函數補充完整,並進行測試*/ linklist mergeAscend(linklist L1,linklist L2)//升序 { linklist head,x,y,p; head=(linklist)malloc(sizeof(node)); head->next=NULL; p=head; x=L1->next; y=L2->next; while(x&&y) { //當比到最好一個元素的時候,會出現x->next=NULL或者是y->next=NULL if(x->info<=y->info)//L1里的數<L2的數 { //這兩句是尾插法的核心 p->next=x; //把新元素插到當前元素后面去 p=x; //吧當前指針指向新元素 x=x->next; } else { //這兩句是尾插法的核心 p->next=y; //把新元素插到當前元素后面去 p=y; //吧當前指針指向新元素 y=y->next; } } p->next=x?x:y; //把最后一個數加進去 return head; } linklist mergeDescend(linklist L1,linklist L2)//降序 { } int main() { linklist h1,h2,h3; h1=creatbyqueue(); /*尾插法建立單鏈表,請輸入升序序列*/ h2=creatbyqueue(); print(h1); print(h2); //升序合並請調用 h3=mergeAscend(h1,h2); //降序合並請調用 // h3=mergeDescend(h1,h2); print(h3); delList(h3); return 0; }
/* /* 設計一個算法linklist interSection(linklist L1,linklist L2), 求兩個單鏈表表示的集合L1和L2的交集,並將結果用一個新的帶頭 結點的單鏈表保存並返回表頭地址。 */ /**********************************/ /*文件名稱:lab3_07.c */ /**********************************/ #include "slnklist.h" /*請將本函數補充完整,並進行測試*/ linklist interSection(linklist L1, linklist L2) { linklist head,p,s,x,y; //s是臨時存儲的結點 head=(linklist)malloc(sizeof(node)); head->next=NULL; p = head; x = L1->next; y = L2->next; while(x) { while(y) { if(x->info==y->info) { s = (linklist)malloc(sizeof(node)); s->info = x->info; p->next = s; //這兩句不能互換,因為是添加數據 p = s; break; //notice,不可省略 ,跳出本層循環 ,不執行y=y->next } y = y->next; } x = x->next; } p->next = NULL; return head; } int main() { linklist h1,h2,h3; h1=creatbyqueue(); /*尾插法建立單鏈表,輸入時請勿輸入重復數據*/ h2=creatbyqueue(); print(h1); /*輸出單鏈表h1*/ print(h2); h3=interSection(h1,h2); /* 求h1和h2的交集*/ print(h3); delList(h1); delList(h2); delList(h3); return 0; }
/* 請編寫一個算法函數void partion(linklist head), 將帶頭結點的單鏈表head中的所有值為奇數的結點調整 到鏈表的前面,所有值為偶數的結點調整到鏈表的后面。 */ /**********************************/ /*文件名稱:lab3_08.c */ /**********************************/ #include "slnklist.h" /*請將本函數補充完整,並進行測試*/ void partion(linklist head) { linklist p,s,pre; pre=head; p=head->next; while(p) { if(p->info%2==0) //偶數 { pre=p; p=p->next; } else { s=p; pre->next=p->next; p=pre->next; s->next=NULL; s->next=head->next; head->next=s; } } } int main() { linklist head; head=creatbyqueue(); /*尾插法建立帶頭結點的單鏈表*/ print(head); /*輸出單鏈表head*/ partion(head); print(head); delList(head); return 0; }
/* 編寫一個程序,用盡可能快的方法返回帶頭結點單鏈表中倒數第k個結點的地址,如果不存在,則返回NULL。 */ /**********************************/ /*文件名稱:lab3_09.c */ /**********************************/ #include "slnklist.h" /*請將本函數補充完整,並進行測試*/ linklist search(linklist head,int k) { linklist p = head->next,x; int count = 0,i; x = p; while(x) //求鏈表長度 { count++; x=x->next; } //獲得倒數第k的值 for(i=0;i<count-k;i++) { p = p->next; } return p; } int main() { int k; linklist head,p; head=creatbyqueue(); /*尾插法建立帶頭結點的單鏈表*/ print(head); /*輸出單鏈表head*/ printf("k="); scanf("%d",&k); p=search(head,k); if (p) printf("%d\n",p->info); else printf("Not Found!\n"); delList(head); return 0; }