问题:
建立一个10结点的单项链表,每个结点包括:学号、姓名、性别、年龄。对其进行排序,采用插入排序法,按学号从小到大排列。
1 //思路1,本问题可以仅仅通过类似于对待一般数组一样,通过不断插入赋值来达到目的;author欲通过仅仅对指针进行操作来完成,避免赋值、提高效率; 2 #include<iostream.h> 3 4 struct person 5 { 6 int num; 7 char name[30]; 8 char sex[7]; 9 int age; 10 person* ptr; 11 }; 12 13 void AddNode(person*, person*, person*);//插入节点函数声明; 14 void DeleteNode(person*, person*);//删除节点函数声明; 15 16 person* head; 17 18 19 void main() 20 { 21 person a[10]= 22 {{11, "jack", "male", 15}, 23 {21, "jim", "male", 14}, 24 {3, "tracy", "female", 15}, 25 {10, "anderson", "male", 21}, 26 {10, "kobe", "male", 28}, 27 {4, "messi", "male", 25}, 28 {12, "ronaldo", "female", 28}, 29 {1, "higuain", "male", 26}, 30 {80, "bale", "male", 28}, 31 {5, "murinio", "male", 35}}; 32 33 person* ptrset[10]= 34 {&a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7], &a[8], &a[9]}; 35 person* temp; 36 37 head=a; 38 for(int i=0;i<9;i++) 39 { 40 a[i].ptr=&a[i+1]; 41 } 42 a[9].ptr=NULL;//构成一个链表; 43 44 int j,k; 45 for(i=1;i<10;i++) 46 { 47 for(j=0;j<i;j++) 48 { 49 if(ptrset[i]->num < ptrset[j]->num)//这里的循环遍历是以ptrset[]数组来进行,而不是a[]; 50 { 51 DeleteNode(ptrset[i], ptrset[i-1]);//1,抽象的链接关系,非数组的连续排列;2,删除一个节点; 52 if(j==0) 53 { 54 ptrset[i]->ptr=head; 55 head=ptrset[i]; 56 } 57 else AddNode(ptrset[j-1], ptrset[j], ptrset[i]);//插入一个节点; 58 59 temp=ptrset[i]; 60 for(k=i-1;k>=j;k--) 61 ptrset[k+1]=ptrset[k]; 62 ptrset[j]=temp;//把ptrset[]数组的顺序关系调整为与链表的一致; 63 } 64 } 65 } 66 67 person* p=head; 68 while(p) 69 { 70 cout<<p->num<<" "<<p->name<<" "<<p->sex<<" "<<p->age<<endl; 71 p=p->ptr; 72 }//输出排序完成后的链表; 73 } 74 75 76 void DeleteNode(person* ptr1, person* ptr2)//per2指向(i-1); ptr1指向(i); 77 { 78 //if(ptr1==head);//分析可知,ptr1是不可能等于head的,所以这里不必再进行分类讨论; 79 ptr2->ptr=ptr1->ptr; 80 ptr1->ptr=NULL; 81 } 82 83 void AddNode(person* ptr3, person* ptr4, person* ptr1)//ptr3指向(j-1), ptr4指向j, ptr5指向i; 84 { 85 ptr3->ptr=ptr1; 86 ptr1->ptr=ptr4; 87 }