双向循环链表的各种排序算法
0 预备函数
预备1 比较函数
// dir = 1 up ; dir = 0 down
int IntCmp(void *vp1, void *vp2, int dir){
int *ip1 = (int *)vp1;
int *ip2 = (int *)vp2;
return dir ? (*ip1 - *ip2) : (*ip2 - *ip1);
}
预备2 链表结点移动函数
使用各种算法对链表进行排序,都有个 “移动结点” 的过程,能否将这个过程封装成函数?供链表的“移动结点”使用?请看下面的函数:
// moving the node from "remove_pos" to "insert_back_pos"
static void moveNode(node *remove_pos, node *insert_back_pos){
// removing remove_pos from the list
remove_pos->pPrev->pNext = remove_pos->pNext;
remove_pos->pNext->pPrev = remove_pos->pPrev;
// Inserting remove_pos at the back of insert_back_pos
remove_pos->pPrev = insert_back_pos;
remove_pos->pNext = insert_back_pos->pNext;
insert_back_pos->pNext->pPrev = remove_pos;
insert_back_pos->pNext = remove_pos;
}
1 O(n^2) 级三大排序
1.1 插入排序法
1.1.1插入排序法实体
// dir = 1 up; dir = 0 down
void InsertionSort_ListWithHead(node *list, int dir, int (*cmpFn)(void *, void *, int)){
int length = CountingNodesOfListWithHead(list);
if(length <= 1){
// Defensive programming
return;
}
for(node *j = list->pNext->pNext; j != list; j = j->pNext){
node *i = j->pPrev;
while( (i != list) && ((cmpFn(&(i->num), &(j->num), dir) > 0 )) ){
i = i->pPrev;
}
node *tmp = j->pPrev; // Record the previous node of "the waiting to insert node"
moveNode(j, i); // This operation changes the original position.
j = tmp; // Revise the "the inner loop variables" to the original position.
}
}
1.1.2 测试例程
#include <stdio.h>
#include "linkedList.h"
int main(int argc, char *argv[]){
int arr[] = {
102, 99, -1, 0, 85, -9, 7, 68};
node *list = createListWithHead_UsingArray(arr, sizeof(arr) / sizeof(arr[0]));
printf(">>> [original material] from header to tailer:\r\n");
printListWithHead_FromHead(list);
InsertionSort_ListWithHead(list, 1, IntCmp);
printf(">>> [Sorted] from header to tailer:\r\n");
printListWithHead_FromHead(list);
printf(">>> [Sorted] from tailer to header:\r\n");
printListWithHead_FromBack(list);
return 0;
}
1.2 冒泡排序法
1.2.1 冒泡排序法实体
// dir = 1 up; dir = 0 down
void BubbleSort_ListWithHead(node *list,