排序算法学了又忘,忘了又学,比较不会忘记的大概只有冒泡排序法了。还是把各种排序算法记录下来,做个笔记,以免下次要重新学习的时候到处找”教材“。
/*
先定义数据类型, 布尔值
*/
typedef
int
Type; type1def
enum
boolean{
false
,
true
}boolean;
一,选择排序。
选择排序的思想是每次都取一个最大(小)的放在第(i)个位置,第一次是放在第一个位置,第二次就放在第二个位置。。。。。。N个要排序就排序N-1次。
/**/
/* * 交换两个位置元素的值*/
void
swap(Type
*
a,
int
pos1,
int
pos2)
...
{ Type temp = a[pos1]; a[pos1] = a[pos2]; a[pos2] = temp; }
/**/
/* * a<b则返回真 * */
boolean compare_lower(Type a,Type b)
...
{ if (a < b) return true ; return false ; }
/**/
/* * 选择排序 * 参数:数组a,其长度len*/
void
select_sort(Type
*
a,
int
len)
...
{ int j,k,m; for (j = 0 ;j < len - 1 ;j ++ ) ... { m = j; for (k = j + 1 ;k < len;k ++ ) if (compare_lower(a[k],a[m]))m = k; if (m != j) swap(a,m,j); } }
二、插入排序
1、在数组上进行插入排序
/**/
/* *一般的插入排序算法*/
/**/
/* *思想:往一个有序的序列按顺序插入一个元素,结果仍是一个有序的序列. * **/
/**/
/* * a<=b则返回真 * */
boolean compare_lower(Type a,Type b)
...
{ if (a <= b) return true ; return false ; }
/**/
/* * a>=b则返回真 * */
boolean compare_larger(Type a,Type b)
...
{ if (a >= b) return true ; return false ; }
void
insert_sort(Type
*
a,
int
len)
...
{ int j = 0 ,k = 0 ,m = 0 ; Type temp; for (j = 1 ;j < len;j ++ ) ... { temp = a[j]; for (k = j - 1 ;k >= 0 ;k -- ) ... { /**/ /* 直到找出比temp(大)小的元素,然后要把temp插到该元素前面 */ if (compare_lower(a[k],temp)) break ; /**/ /* 向后移动 */ a[k+ 1 ] = a[k]; } if (temp != a[k + 1 ])a[k + 1 ] = temp; } }
2、在链表上进行插入排序
typedef
struct
myList
...
{ Type elem; struct myList * pre; struct myList * next; }
m_List,
*
List;
const
int
LEN
=
sizeof
(m_List);
/**/
/* 这里省略了初始化链表的函数 */
/**/
/* 插入排序 */
void
insert_sort(List head)
...
{ if (head -> next == NULL) return ; List unsort_head = head -> next; List current; List temp; for (;unsort_head != NULL;unsort_head = unsort_head -> next) ... { current = unsort_head; temp = head -> next; /**/ /* 从左开始至当前(current)元素,找出比current大的元素,然后插到该元素前面 */ while (temp -> elem < current -> elem && temp != current) /**/ /* 比current小,移动下一个 */ ... { /**/ /* 向后移动 */ temp= temp -> next; } if (temp != current) ... { /**/ /* 先拆开 */ current-> pre -> next = current -> next; if (current -> next != NULL)current -> next -> pre = current -> pre; /**/ /* 插入到合适位置 */ temp-> pre -> next = current; current -> pre = temp -> pre; current -> next = temp; temp -> pre = current; } } }
3、折半插入排序
void
bin_insert_sort(
int
*
a,
int
len)
...
{ int low,mid,high,j,k; int temp; for (j = 1 ;j < len;j ++ ) ... { temp = a[j]; low = 0 ; high = j - 1 ; /**/ /* 在low与high之间,查找合适位置 */ while (low <= high) ... { mid = (low + high) / 2 ; /**/ /* 如果要插入的元素比较大,则到右边找 */ if (temp > a[mid])low = mid + 1 ; /**/ /* 否则在左边找 */ else high = mid - 1 ; } /**/ /* 移动元素到后面 */ for (k = j - 1 ;k >= low;k -- ) ... { a[k + 1 ] = a[k]; } a[low]= temp; } }
4、希尔排序
/**/
/* * 希尔排序 * 原理:一种分组插入排序方法.先取定一个小于序列长度n的整数m作为第一个增量, * 把表的全部记录分成?个组 * 所有距离为m的倍数的记录放在同一个组中,在各组内进行排序(一般用直接插入排序,也可用其它); * 然后取第二个增量m/2,重复到所有记录放在同一组. */
void
shell_sort(
int
*
a,
int
len)
...
{ int j,k,m; int temp; /**/ /* m:表示相隔m为一组 */ m= len / 2 ; /**/ /* 分组数不为1,则继续循环 */ while (m > 0 ) ... { /**/ /* j: */ for (j = m;j < len;j ++ ) ... { temp = a[j]; /**/ /* k>=0且a[k]大于temp,则移动元素 */ for (k = j - m;k >= 0 && a[k] > temp;k -= m) ... { a[k + m] = a[k]; } /**/ /* 插入到合适位置 */ a[k+ m] = temp; } m/= 2 ; } }
据说 m=3*m+1 的增量效率不错.
void
shell_sort(
int
*
a,
int
len)
...
{ int j,k,m,n; int temp; int increaments[ 20 ]; /**/ /* 先把增量存放在数组中 */ for (j = 0 ,m = 1 ;m < len;j ++ ) ... { increaments[j] = m; m = 3 * m + 1 ; } /**/ /* j 确定了增量数组个数 */ for (j -- ;j >= 0 ;j -- ) ... { m = increaments[j]; for (k = m;k < len;k ++ ) ... { temp = a[k]; /**/ /* n>=0且a[n]大于temp,移动元素 */ for (n = k - m;n >= 0 && a[n] > temp;n -= m) ... { a[n + m] = a[n]; } a[n+ m] = temp; } } }
三、交换排序
1、经典的冒泡排序法
void
bubble_sort(
int
*
a,
int
len)
...
{ int j,k; int temp; int change = 1 ; for (j = 0 ;(j < len - 1 ) && change;j ++ ) ... { change = 0 ; for (k = j + 1 ;k < len;k ++ ) ... { if (a[k - 1 ] > a[k]) ... { change = 1 ; temp = a[k - 1 ]; a[k - 1 ] = a[k]; a[k] = temp; } } } }
暂时这么多,日后复习再更新。