鏈表排序講解:
head指針指向鏈表的頭結點,是找到整個鏈表的唯一依據,如果head指針丟失,整個鏈表就找不到了。
head存儲的是第一個節點的地址,head->next存儲的是第二個節點的地址; 任意一個節點p的地址,只能通過它前一個節點的next來求得。
單向鏈表的選擇排序圖示: ---->[1]---->[3]---->[2]...---->[n]---->[NULL](原鏈表)
head 1->next 3->next 2->next n->next
選擇排序(Selection sort)是一種簡單直觀的排序算法。
首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然後,再從剩余未排序元素中繼續尋找最小元素,然後放到排序序列末尾。以此類推,直到所有元素均排序完畢。
動畫演示:http://www.nowamagic.net/librarys/veda/detail/1849
選擇排序
定義的結構體
struct student { char ID[11]; //學生學號 char name[20]; //學生姓名 struct student *next; //next 指針 指向 struct student 類型的變量 }stu;
裡面的變量均為數組
那怎麼實現結構體中定義(有)數組變量,鏈表遍歷結構體,按照結構體裡面變量來排序呢?
其中對數組比較大小、比較兩個字符串的大小來使用的函數是: strcmp()
對數組之間的賦值函數是 strcpy()
升序:
/*************** 函數功能: 升序排列出勤學生 返回:指向鏈表表頭的指針 /***************/ struct student *sort_message_order(struct student* head) //升序 按照ID順序 { struct student *Back,*pointer; //p指針指向新的節點 back指針指向鏈表的尾節點 struct student temp; // 定義結構體student別名,typedef也可以定義的結構體別名 Back=head->next; pointer=head->next; //跳過頭結點 指向下一個節點 頭結點中沒有學生信息 while(Back!=NULL) //如果尾節點不為空 就一直遍歷下去 { while(pointer->next!=NULL) //如果指向新開辟的結點不為空就一直遍歷下去 { pointer=pointer->next; //指向下一個新開辟的結點 if ( strcmp( Back->ID,pointer->ID)>0 ) //如果back->ID大於pointer->ID就返回大於0的值;後面大於前面的 往後放 { strcpy(temp.ID,Back->ID); strcpy(temp.name,Back->name); //把尾節點值賦值給臨時temp結構體變量 strcpy( Back->ID,pointer->ID); strcpy(Back->name,pointer->name); //把指向的新節點 跟尾節點交換 位置 strcpy(pointer->ID,temp.ID); strcpy(pointer->name,temp.name);//將臨時temp結構體變量賦值給指向的結構體變量 } } Back=Back->next; //指向下一個尾節點 pointer=Back; //指向尾節點 } return head; //返回頭結點 }
降序:
/*************** 函數功能: 降序排列出勤學生 返回:指向鏈表表頭的指針 /***************/ struct student * sort_message_Desc(struct student* head)//Descending降序 { struct student *Back,*pointer; //p總是指向新申請的結點 back總是指向鏈表的尾節點 struct student temp; Back=head->next; pointer=head->next;//跳過頭結點,頭結點中沒有學生信息 while(Back!=NULL) { while(pointer->next!=NULL) { pointer=pointer->next; if ( strcmp( Back->ID,pointer->ID)<0 ) // back->ID小於pointer->ID返回負數 把最小的 往後放 降序 { strcpy(temp.ID,Back->ID); strcpy(temp.name,Back->name); //把尾節點值賦值給臨時temp結構體變量 strcpy( Back->ID,pointer->ID); strcpy(Back->name,pointer->name); //指向的新節點 跟尾節點交換 位置 strcpy(pointer->ID,temp.ID); strcpy(pointer->name,temp.name); //將臨時temp結構體變量賦值給指向的結構體變量 } } Back=Back->next; //指向下一個尾節點 pointer=Back; //指向尾節點 } return head; //返回頭結點 }
輸出打印鏈表內容:
void Print_List(struct student *head) { struct student* pointer; pointer=head->next; //跳過無數據的頭結點 while(pointer!=NULL) { printf(" ",pointer->ID); printf(" ",pointer->name); pointer=pointer->next;//指向下一個節點 } }