排序

//快速排序

//排序思想

//1.從數列中挑出一個元素,稱爲 “基準”(pivot),

//2.重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面(相同的數可以到任一邊)。在這個分區退出之後,該基準就處於數列的中間位置。這個稱爲分區(partition)操作。

//3.遞歸地(recursive)把小於基準值元素的子數列和大於基準值元素的子數列排序

wKiom1c6z2ODq26tAAFrWtvqt58860.gif

int PartSort(int* a, int left, int right)
{
	int key = a[right];//找最右邊一個爲基準
	int begin = left;
	int end = right - 1;
	while (begin < end)
	{
		while (begin < end&&a[begin] <= key)//當找到大於基準數時停
		{
			++begin;
		}
		while (begin < end&&a[end] >= key)//當找到小於基準數時停
		{
			--end;
		}
		if (begin < end)
		{
			swap(a[begin], a[end]);
		}
	}
	if (a[begin]>a[right])
	{
		swap(a[begin], a[right]);
		return begin;
	}
	else
	{
		return right;
	}
}
void QuickSort(int* a, int left, int right)  //快排
{
	assert(a);
	if (left >= right)
		return;
	int div = PartSort(a, left, right);   
	QuickSort(a, left, div - 1);
	QuickSort(a, div+1, right);
}

堆排序

//堆排序
void AdjustDown(int* a, size_t size, size_t parent)
{
	size_t child = parent * 2 + 1;
	while (child < size)
	{
		if (child + 1 < size&&a[child]< a[child + 1])
		{
			++child;
		}
		if (a[child] > a[parent])
		{
			swap(a[child], a[parent]);
			parent= child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}
void HeapSort(int*a ,size_t size)
{
	assert(a);
	for (int i = (size - 2) / 2; i >= 0; --i)  //建堆
	{
		AdjustDown(a, size, i);
	}
	for (size_t i = 0; i < size; ++i)
	{
		swap(a[0], a[size - i - 1]);
		AdjustDown(a, size - i - 1, 0);
	}
}

排序效果:

wKioL1c60H7TdI_sAARJvLiNWU4473.gif

選擇排序:

設計思想:

//選擇排序(Selection sort)是一種簡單直觀的排序算法。

//它的工作原理如下。首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然後,再從剩餘未排序元素中繼續尋找最小元素,然後放到排序序列末尾。

//以此類推,直到所有元素均排序完畢。

void SelectSort(int* a, size_t size)   //選擇排序
{
	assert(a);
	for (size_t i = 0; i < size-1; i++)
	{
		int min = i;
		//查找最小值
		for (size_t j = i+1; j < size; j++)
		{
			if (a[min]>a[j])
			{
				min = j;
			}
		}
		//交換
		if (min!=i)
		{
			swap(a[min], a[i]);
		}
	}
}

排序效果:

wKioL1c60I2AHbuyAAA0SbQuz3M741.gif

//冒泡排序

//排序思想:

//1、比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。

//2、對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對。在這一點,最後的元素應該會是最大的數。

//3、針對所有的元素重複以上的步驟,除了最後一個。

//4、每次對越來越少的元素重複上面的步驟,直到沒有任何一對數字需要比較。

//void BubbleSort(int* a,size_t size)
//{
//	for (size_t i = 0; i < size-1; ++i)
//	{
//		for (size_t j = i + 1; j < size; ++j)
//		{
//			if (a[i]>a[j])
//			{
//				swap(a[i], a[j]);
//			}
//		}
//	}
//}
//改進
void bubbleSort1(int* a, int size)
{
	int j = 0;
	while (size > 0)
	{
		for (j = 0; j < size - 1; j++)
		{
			if (a[j] > a[j + 1])
			{
				swap(a[j], a[j + 1]);
			}
		}
		size--;
	}
}

插入排序:

設計思想:

1.從第一個元素開始,該元素可以認爲已經被排序

2.取出下一個元素,在已經排序的元素序列中從後向前掃描

3.如果該元素(已排序)大於新元素,將該元素移到下一位置

4.重複步驟3,直到找到已排序的元素小於或者等於新元素的位置

5.將新元素插入到該位置中

6.重複步驟2

void InsertSort(int *a, int size)    //插入排序
{
	assert(a);
	for (int i = 1; i < size; i++)
	{
		int cur = i;
		int next = a[i];
		while (i >=0 && a[cur-1] > next)
		{
			a[cur] = a[cur-1];
			--cur;
		}
		a[cur] = next;
	}
}

希爾排序,也稱遞減增量排序算法,是插入排序的一種高速而穩定的改進版本。

該方法的基本思想是:

先將整個待排元素序列分割成若干個子序列(由相隔某個“增量”的元素組成的)分別進行直接插入排序,然後依次縮減增量再進行排序,待整個序列中的元素基本有序(增量足夠小)時,再對全體元素進行一次直接插入排序。

因爲直接插入排序在元素基本有序的情況下(接近最好情況),效率是很高的.

希爾排序是基於插入排序的以下兩點性質而提出改進方法的:

1、插入排序在對幾乎已經排好序的數據操作時,效率高, 即可以達到線性排序的效率

2、但插入排序一般來說是低效的, 因爲插入排序每次只能將數據移動一位>

void ShellSort(int* a,size_t size)
{
	int gap = size;
	while (gap > 1)
	{
		gap = gap / 3 + 1;
		for (size_t i = 0; i < size - gap; i++)
		{
			int end=i;
			int tmp = a[end + gap];
			while (end >= 0 && a[end] > tmp)
			{
				swap(a[end + gap], a[end]);
				end -= gap;
			}
			a[end + gap] = tmp;
		}
	}
}

排序效果:

wKiom1c6z7nyhkxqAAuT3ewzFDs482.gif


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