內部排序算法

快排非遞歸:

#include <stdio.h>
#include <stdlib.h>

int partition(int s[], int i, int j)
{
	int value = 0;
	int flag = 1; //判斷該從頭循環還是尾循環
	value = s[i];
	while(i<j)
	{
		switch(flag)
		{
		case 0:
			if(s[i] < value)
				i++;
			else
			{
				s[j--] = s[i];
				flag = 1;
			}
			break;
		case 1:
			if(s[j] >= value)
				j--;
			else
			{
				s[i++] = s[j];
				flag = 0;
			}
			break;
		}
	}
	s[i] = value;
	return i;
}

void quick_sort(int s[], int l, int r)
{
	int *stack = (int *)malloc(sizeof(int)*(r-l+1));
	int top = 0;
	int index1, index2;
	int res;
	stack[top++] = r;
	stack[top++] = l;
	while(top!=0)
	{
		index1 = stack[--top];
		index2 = stack[--top];
		res = partition(s, index1, index2);

		if(res != index2) //後部分partiton未結束
		{
			stack[top++] = index2;
			stack[top++] = res+1;
		}
		if(res != index1) //前部分partion未結束
		{
			stack[top++] = res-1;
			stack[top++] = index1;
		}
	}
	free(stack);
	stack = NULL;
}

int main()
{
	int number[10] = {8, 1, 8, 4, 9, 5, 8, 10, 3, 6};
	quick_sort(number, 0, 9);
	int i;
	for(i=0; i<10; i++)
	{
		printf("%d, ", number[i]);
	}
	printf("\n");
	return 0;
}



快排遞歸:

#include <stdio.h>
#include <stdlib.h>

int partition(int s[], int i, int j)
{
	int value = 0;
	int flag = 1; //判斷該從頭循環還是尾循環
	value = s[i];
	while(i<j)
	{
		switch(flag)
		{
		case 0:
			if(s[i] < value)
				i++;
			else
			{
				s[j--] = s[i];
				flag = 1;
			}
			break;
		case 1:
			if(s[j] >= value)
				j--;
			else
			{
				s[i++] = s[j];
				flag = 0;
			}
			break;
		}
	}
	s[i] = value;
	return i;
}

void quick_sort(int s[], int l, int r)
{
	int res;
	if(l<r)
	{
		res = partition(s, l, r);
		quick_sort(s, l, res-1);
		quick_sort(s, res+1, r);
	}
}

int main()
{
	int number[10] = {8, 1, 8, 4, 9, 5, 8, 10, 3, 6};
	quick_sort(number, 0, 9);
	int i;
	for(i=0; i<10; i++)
	{
		printf("%d, ", number[i]);
	}
	printf("\n");
	return 0;
}


快排另一種形式:(單鏈錶快排)

詳見:http://blog.csdn.net/otuhacker/article/details/10366563

struct LNode {
	int key;
	LNode *next;
	LNode(int key):key(key), next(NULL) {}
};

// 兩個指針p、q沿next向後遍歷,並保證p之前的元素(除首元素外)比key小, p與q之間的元素(除p所指元素外)比key大
// 最後交換首元素和p所指元素的值
LNode *Partition(LNode *begin, LNode *end) {
	int key = begin->key;
	LNode *p = begin;
	LNode *q = begin->next;
	int temp = 0;
	while (q != end) {
		if (q->key < key) {
			p = p->next;
			temp = p->key;
			p->key = q->key;
			q->key = temp;
		}
		q = q->next;
	}
	temp = begin->key;
	begin->key = p->key;
	p->key = temp;
	return p;
}

// 調用時end賦值爲NULL
void QuickSort(LNode *begin, LNode *end) {
	if (begin != end) {
		LNode *partition = Partition(begin, end);
		QuickSort(begin, partition);
		QuickSort(partition->next, end);
	}
}



堆排序

#include <iostream>
#include <vector>

using namespace std;

// 堆排序中, 第i個元素的左孩子的標號爲2*i,右孩子的標號爲2*i+1
// 連續數組中, 如果i從0開始, 則第i個元素的左孩子的標號爲2*i+1, 右孩子的標號爲2*i+2

void HeapAdjust(vector<int>& nums, int start, int end) {
	int num = nums[start];
	for (int i = 2 * start + 1; i <= end; i = i * 2 + 1) { // 大頂堆
		if (i < end && nums[i] <= nums[i+1])
			i++;
		if (num >= nums[i])
			break;
		nums[start] = nums[i];
		start = i;
	}
	nums[start] = num;
}

void HeapSort(vector<int>& nums) {
	if (nums.size() <= 1) return;

	// 從最後一個非葉子節點開始堆調整,直到根節點截止
	for (int i = nums.size()/2-1; i >= 0; i--) {
		HeapAdjust(nums, i, nums.size()-1);
	}
	for (int i = nums.size()-1; i > 0; i--) {
		// 將堆頂元素(當前最大元素)與數組第i個元素交換,從而使第i大的元素位置固定
		nums[0] = nums[0] ^ nums[i];
		nums[i] = nums[0] ^ nums[i];
		nums[0] = nums[0] ^ nums[i];

		// 重新調整前i個元素爲大頂堆
		HeapAdjust(nums, 0, i-1);
	}
}


int main() {
	vector<int> nums;
	int n;
	int val;
	while (cin >> n) {
		for (size_t i = 0; i < n; i++) {
			cin >> val;
			nums.push_back(val);
		}
		HeapSort(nums);

		for (size_t i = 0; i < nums.size(); i++) {
			cout << nums[i] << " ";
		}
		cout << endl;

		nums.clear();
	}
	return 0;
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章