最近写了一串经典的排序算法,分享一下:
//author: tigermei
//date: 2/20/2011
//打印出数组里面的元素
void print_arr(int array[], int n);
//交换数组里面的两个数字
void swap(int array[], int one, int two);
第一类:插入排序///
//插入排序
void insert_sort(int array[], int start, int end);
//折半插入排序
void insert_sort_ex(int array[], int start, int end);
//希尔排序
void shell_sort(int array[], int start, int end);
/第二类:简单选择排序///
//简单选择排序
void simple_select_sort(int array[], int start, int end);
/第三类:交换排序///
//快速排序
void quick_sort(int array[], int start, int end);
//冒泡排序
void bubble_sort(int array[], int start, int end);
第四类:二路归并排序///
//归并排序
void merge_sort(int array[], int start, int end);
第五类:堆排序///
//堆排序
void heap_sort(int array[], int start, int end);
第六类:基数排序///
//基数排序
void basenum_sort(int array[], int n);
一. 插入排序:
//插入排序
void insert_sort(int array[], int start, int end)
{
int i, j;
for(i = start + 1 ; i <= end; ++i )
{
for(j = i - 1 ; start <= j ; --j)
{
if(array[j] > array[j + 1])
swap(array, j, j + 1);
else
break;
}
}
}
//折半插入排序
void insert_sort_ex(int array[], int start, int end)
{
int i, j;
for(i = start + 1 ; i <= end; ++i)
{
int des = array[i];
int first = start, second = i - 1;
int mid ;
while(first <= second)
{
mid = (first + second ) / 2;
if(array[mid] < array[i])
first = mid + 1;
else if(array[mid] >= array[i])
second = mid - 1;
}
for(j = i - 1; second < j ; --j)
array[j + 1] = array[j];
if(second < i)
array[second + 1] = des;
}
}
//希尔排序
void shell_sort(int array[], int start, int end)
{
int le = end - start;
for(int sd = le / 2; 1 <= sd ; sd = sd / 2)
{
int i, j;
for(i = start + sd ; i <= end; i += sd )
{
for(j = i - sd ; start <= j ; j -= sd)
{
if(array[j] > array[j + sd])
swap(array, j, j + 1);
else
break;
}
}
}
}
//插入排序
void insert_sort(int array[], int start, int end)
{
int i, j;
for(i = start + 1 ; i <= end; ++i )
{
for(j = i - 1 ; start <= j ; --j)
{
if(array[j] > array[j + 1])
swap(array, j, j + 1);
else
break;
}
}
}
//折半插入排序
void insert_sort_ex(int array[], int start, int end)
{
int i, j;
for(i = start + 1 ; i <= end; ++i)
{
int des = array[i];
int first = start, second = i - 1;
int mid ;
while(first <= second)
{
mid = (first + second ) / 2;
if(array[mid] < array[i])
first = mid + 1;
else if(array[mid] >= array[i])
second = mid - 1;
}
for(j = i - 1; second < j ; --j)
array[j + 1] = array[j];
if(second < i)
array[second + 1] = des;
}
}
//希尔排序
void shell_sort(int array[], int start, int end)
{
int le = end - start;
for(int sd = le / 2; 1 <= sd ; sd = sd / 2)
{
int i, j;
for(i = start + sd ; i <= end; i += sd )
{
for(j = i - sd ; start <= j ; j -= sd)
{
if(array[j] > array[j + sd])
swap(array, j, j + 1);
else
break;
}
}
}
}
二. 简单选择排序
//简单选择排序
void simple_select_sort(int array[], int start, int end)
{
int i, j;
for(i = start; i <= end; ++i)
{
int minimal = array[i];
int minIndex = i;
for(j = i + 1; j <= end; ++j)
{
if(minimal > array[j])
{
minimal = array[j];
minIndex = j;
}
}
if(i != minIndex)
swap(array, i, minIndex);
}
}
三. 交换排序
//快速排序
static int partion_sort(int array[], int start, int end);
int partion_sort(int array[], int start, int end)
{
if(start >= end)
return start;
int i = start + 1, j = end;
while(i <= j)
{
while( array[i] <= array[start] && i <= j)
++i;
while(array[start] < array[j] && i <= j)
--j;
if(i <= j)
swap(array, i, j);
else
break;
}
if(array[j] < array[start])
swap(array, start, j);
return j;
}
void quick_sort(int array[], int start, int end)
{
int mid = partion_sort(array, start, end);
/* sort the first part*/
if( start < mid - 1)
quick_sort(array, start, mid - 1);
/* sort the second part*/
if(mid + 1 < end)
quick_sort(array, mid + 1, end);
}
//冒泡排序
void bubble_sort(int array[], int start, int end)
{
int i, j;
for(i = start; i <= end; ++i)
{
bool sequence = true;
for(j = end; i + 1<= j; --j)
{
if(array[j - 1] > array[j])
{
swap(array, j - 1, j);
sequence = false;
}
}
if(sequence)
break;
}
}
四. 归并排序
static void merge_sort_imp(int array[], int start, int end);
static void merge(int array[], int start, int mid, int end);
int *temp_array = NULL;
void merge(int array[], int start, int mid, int end)
{
if(!temp_array)
{
assert(false);
return;
}
for(int i = 0; i <= end ; ++i)
temp_array[i] = array[i];
//比较前后两部分数字的大小,写入到结果数组里面
int i = start, j = mid, index = start;
while(i <= mid - 1 && j <= end)
{
if(array[i] <= array[j])
{
temp_array[index++] = array[i];
++i;
}
else
{
temp_array[index++] = array[j];
++j;
}
}
//下面两段代码只有一段会得到执行
while(i <= mid - 1)
{
temp_array[index++] = array[i];
++i;
}
while(j <= end)
{
temp_array[index++] = array[j];
++j;
}
for(int m = start; m <= end; ++m)
array[m] = temp_array[m];
}
void merge_sort_imp(int array[], int start, int end)
{
int len = end - start;
if(len <= 0) //归并排序,这里当这里的len长度很小的时候可以选择其他的排序算法,可以减少堆栈的长度
return;
int mid = (start + end ) / 2;
//分治前半部分
merge_sort_imp(array, start, mid);
//分治后半部分
merge_sort_imp(array, mid + 1, end);
//合并前后两个部分
merge(array, start, mid + 1, end);
}
//归并排序
void merge_sort(int array[], int start, int end)
{
int len = end - start + 1;
if(len <= 1 || start < 0)
return;
//新建临时内存存储需要排序的数组
if(temp_array)
delete [] temp_array;
temp_array = new int[end + 1];
for(int i = start; i <= end; ++i)
temp_array[i - start] = array[i];
merge_sort_imp(array, start, end);
delete [] temp_array;
}
五. 堆排序
//建堆
static void build_max_heap(int array[], int start, int end);
//将元素k进行下沉
static void adjust_down(int array[], int k, int start, int end);
void build_max_heap(int array[], int start, int end)
{
//做 end - start 次下沉操作就可以建立出最大堆了
for(int i = (end - 1) / 2; start <= i ; --i)
{
adjust_down(array, i, i, end);
}
}
void adjust_down(int array[], int k, int start, int end)
{
int child = 2*k + 1, i = k;
while(child <= end)
{
if(child + 1 <= end && array[child] < array[child + 1] )
child = child + 1;
if(array[i] < array[child])
{
swap(array, i, child);
i = child;
child = 2*i + 1;
}
else
break;
}
}
//堆排序
void heap_sort(int array[], int start, int end)
{
//建立最大堆
build_max_heap(array, start, end);
for(int i = end; start < i ; --i)
{
swap(array, i, start);//输出堆顶元素,与堆底元素交换
adjust_down(array, start, start, i - 1);//调整堆顶的元素,将它下沉
}
}
六. 基数排序
#define MAX_QUEUE 10
//下面新建的链表是没有头部的
typedef struct _LISTNODE
{
int data;
struct _LISTNODE *next;
struct _LISTNODE()
{
next = NULL;
data = -1;
}
}ListNode;
typedef struct _QUEUE
{
struct _QUEUE()
{
head = NULL;
}
ListNode *head;
}Queue;
static void alloc_queue(Queue **queue, int queue_len);
static void disalloc_List(ListNode *list);
static void disalloc_queue(Queue *queue, int queue_len);
static void alloc_list(int array[], int n, ListNode **head);
static int cal_distriubute_collect_num(ListNode *list);
static void distribute(Queue *queue, int queue_len, int k_distribute, ListNode *head);
static void collect(Queue *queue, int queue_len, ListNode **head);
static void distribute_collect(Queue *queue, int queue_len, ListNode **head);
static void output_arr(int array[], int n, ListNode *list);
void alloc_queue(Queue **queue, int queue_len)
{
if(queue_len <= 0 || !queue)
return;
disalloc_queue(*queue, queue_len);
(*queue) = new Queue[queue_len];
}
void disalloc_List(ListNode *list)
{
ListNode *cur = list;
while(cur)
{
ListNode *tmp = cur;
cur = cur->next;
if(tmp)
{
delete []tmp;
tmp = NULL;
}
}
}
void disalloc_queue(Queue *queue, int queue_len)
{
if(!queue)
return;
int i;
for(i = 0; i < queue_len; ++i)
{
disalloc_List(queue[i].head);
}
delete []queue;
}
void alloc_list(int array[], int n, ListNode **head)
{
if(!head)
return;
ListNode *listCur = NULL;
for(int i = 0; i < n; ++i)
{
ListNode *curNode = new ListNode;
curNode->data = array[i];
if(i == 0)
{
*head = curNode;
listCur = curNode;
}
else
{
listCur->next = curNode;
listCur = listCur->next;
}
}
}
int cal_distriubute_collect_num(ListNode *list)
{
int num = 0;
if(!list) return 0;
ListNode *node = list, *maxNode = list;
while(node)
{
if(node->data > maxNode->data)
maxNode = node;
node = node->next;
}
int maxData = maxNode->data;
while(1 <= maxData)
{
num = num + 1;
maxData = maxData / 10;
}
return num;
}
void distribute(Queue *queue, int queue_len, int k_distribute, ListNode *head)
{
//计算当前位置的基数
int baseNum1 = 1;
for(int j = k_distribute - 1; 0 < j ; --j)
baseNum1 = baseNum1 * 10;
ListNode *node = head;
while(node)
{
//计算位于第几个队列
int tmpData = node->data;
tmpData = tmpData / baseNum1;
tmpData = tmpData % 10;
if(tmpData >=queue_len)
continue;
//将当前的节点移到队列中
ListNode *tmpNode = queue[tmpData].head, *nexNode = node->next;
if(tmpNode)
{
while(tmpNode->next)
tmpNode = tmpNode->next;
tmpNode->next = node;
node->next = NULL;
}
else
{
queue[tmpData].head = node;
queue[tmpData].head->next = NULL;
}
node = nexNode;
}
}
void collect(Queue *queue, int queue_len, ListNode **head)
{
ListNode *node = NULL;
if(!head)
return;
int i;
for(i = 0; i < queue_len; ++i)
{
ListNode *tmpNode = queue[i].head;
if(!tmpNode) continue;
if(!*head && tmpNode)
{
*head = queue[i].head;
node = queue[i].head;
}
else
node->next = tmpNode;
queue[i].head = NULL;
while(node && node->next)
node = node->next;
}
return;
}
void distribute_collect(Queue *queue, int queue_len, ListNode **head)
{
if(!head && !*head)
return;
//最大的数字位数
int num = cal_distriubute_collect_num(*head);
//根据各个数字来分配和收集
for(int i = 1; i <= num ; ++i)
{
//分配
distribute(queue, queue_len, i, *head);
*head = NULL;
//收集
collect(queue, queue_len, head);
}
return;
}
void output_arr(int array[], int n, ListNode *list)
{
if(!list)
return;
ListNode *node = list;
int i;
for(i = 0; i < n && node ; ++i, node = node->next)
{
array[i] = node->data;
}
}
//暂时只支持整数
void basenum_sort(int array[], int n)
{
if(n <= 0)
return;
Queue *queue = NULL;
ListNode *list = NULL;
//分配队列
alloc_queue(&queue, MAX_QUEUE);
//分配链表
alloc_list(array, n, &list);
//分配收集队列以达到排序的目的
distribute_collect(queue, MAX_QUEUE, &list);
//向数组里面输出
output_arr(array, n, list);
//析构分配的链表和队列
disalloc_List(list);
disalloc_queue(queue, MAX_QUEUE);
}