基本思想:待排序内容被分为有序和无序两部分,从有序子列表头(尾)向后(前)考察,直至当前值不小于(不大于)无序子列表首元,此时找到插入位置,执行插入操作。
首先是数组的插入排序,我写了三个版本
#include
/* 数组的插入排序,结果为从小到大,倒序检索,允许重复值 */
void insertionSort(int a[])
{
int i, j, k, r, temp;
for(i=0,j=1;j
=0 && a[k]>a[j]; k--) /* 找寻插入位置,倒序检索,逻辑与两边的顺序应是不能交换的,若交换k=-1时,程序先判断a[k]会出错 */
;
if(k < i){ /* 若a[i]
k; r--)
a[r] = a[r-1]; /* 挪动元素 */
a[k] = temp; /* 插入 */
}
}
}
/* 数组的插入排序,结果为从小到大,正序检索,允许重复值 */
void insertionSort(int a[])
{
int i, j, k, r, temp;
for(i=0,j=1;j
k; r--)
a[r] = a[r-1];
a[k] = temp;
}
}
}
/* 数组插入排序,结果从小到大,倒序检索,不允许重复值 */
void insertionSort(int a[], int *len)
{
int i, j, k, r, temp;
for(i=0,j=1; j
=0 && a[k]>a[j]; k--) ; if(k < i && a[k] != a[j]){ for(r=j; r>k; r--) a[r] = a[r-1]; a[k] = temp; } if(a[k] == a[j]){ for(r=j; r<(*len)-1; r++) a[r] = a[r+1]; (*len)--; } } }
然后是链表的插入排序,因为使用的是单链表,故不能倒序检索。同时链表也不能像数组用下标来控制找寻插入点的循环,只能用值来判断,相等一定会推出循环,但这里的相等有两种可能:1~last中有相等的;1~last都比first小。
/* 无辅助表元,更改节点链接顺序,不更改节点内容 */
struct Node{
int value;
struct Node *next;
};
struct Node *insertSort(struct Node *head)
{
struct Node *last, *first, *cur, *pre;
if(head == NULL)
return NULL;
/* 对非空链表进行操作 */
last = head;
first = head->next;
while(first != NULL){
for(pre=NULL,cur=head; cur->value
value; pre=cur,cur=cur->next)
;
if(cur->value == first->value && cur != first){ /* 重复节点,删除;cur有可能与first相等此时不能执行删除 */
last->next = first->next;
free(first);
first = last->next; /* 调整无序子列表首元素位置 */
}
if(cur->value > first->value){
if(pre != NULL){
last->next = first->next;
pre->next = first;
first->next = cur;
first = last->next; /* 调整无序子列表首元素位置 */
}
if(pre == NULL){
last->next = first->next;
head = first;
first->next = cur;
first = last->next; /* 调整无序子列表首元素位置 */
}
}else{
last = first; /* 调整有序和无序子列表末元和首元的位置 */
first = first->next;
}
}
return head;
}
/* 有辅助表元,更改连接顺序, 辅助表元的存在使得头指针不会被更改,因而函数不需要返回指针值 */
void struct Node(struct Node *head)
{
struct Node *last, *first, *cur, *pre;
if(head == NULL)
return;
if(head != NULL && head->next == NULL)
return NULL;
/* 上面一段不直接写成if(head->next == NULL) return; 是因为head若为NULL,head->next会被报错 */
last = head->next;
first = head->next->next;
while(first != NULL){
for(pre=head,cur=head->next; cur->value
value; pre=cur,cur=cur->next)
;
if(cur->value == first->value && cur != first){
last->next = first->next;
free(first);
first = last->next;
}
if(cur->value>first->value){
last->next = first->next;
pre->next = first;
first->next = cur;
first = last->next;
}else{
last = first;
first = first->next;
}
}
}