基础排序算法

最近写了一串经典的排序算法,分享一下:

//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);
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值