C++排序算法

選擇

void select_sort(int arr[], size_t len)
{
	//for (int i = 0; i < len - 1; ++i)
	//{
	//	for (int j = i + 1; j < len; ++j)
	//	{
	//		if (arr[i] > arr[j])
	//		{
	//			int tempVal = arr[i];
	//			arr[i] = arr[j];
	//			arr[j] = tempVal;
	//		}
	//	}
	//}
	int tempVal;
	int j;
	for (int i = 0; i < len - 1; ++i)
	{
		for (j = i + 1; j < len; ++j)
		{
			if (arr[i] > arr[j])
			{
				tempVal = arr[i];
				arr[i] = arr[j];
				arr[j] = tempVal;
			}
		}
	}
}

冒泡

void bubble_sort(int arr[], size_t len)
{
	int tempVal;
	int j;
	for (int i = 0; i < len - 1; ++i)
	{
		for (j = 0; j < len - 1 - i; ++j)
		{
			if (arr[j] > arr[j + 1])
			{
				tempVal = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tempVal;
			}
		}
	}
}

插入

int tempVal;
	int j;
	for (int i = 1; i < len; ++i)//確定插入過程中需要插入元素的下標用i表示
	{
		for (j = i - 1; j >= 0; --j)//j爲已序的序列的最後一個元素下標
		{
			if (arr[j + 1] < arr[j])//如果待插入的元素和最後一個元素進行判斷
			{
				tempVal = arr[j + 1];
				arr[j + 1] = arr[j];
				arr[j] = tempVal;
			}
			else
				break;
		}
	}

優化

int tempVal;
	int j;
	for (int i = 1; i < len; ++i)//確定插入過程中需要插入元素的下標用i表示
	{
		tempVal = arr[i];//保存一下待插入的元素
		for (j = i - 1; j >= 0; --j)//j爲已序的序列的最後一個元素下標
		{
			if (tempVal < arr[j])
			{
				arr[j + 1] = arr[j];
			}
			else
				break;
		}
		arr[j + 1] = tempVal;//把保存的元素放在對應的位置
	}
int tempVal;
	int j;
	for (int i = 1; i < len; ++i)//確定插入過程中需要插入元素的下標用i表示
	{
		tempVal = arr[i];//保存一下待插入的元素
		for (j = i - 1; j >= 0 && tempVal < arr[j]; --j)//j爲已序的序列的最後一個元素下標
		{
			arr[j + 1] = arr[j];
		}
		arr[j + 1] = tempVal;//把保存的元素放在對應的位置
	}
int tempVal;
	int j;
	for (int i = 1; i < len; ++i)//確定插入過程中需要插入元素的下標用i表示
	{
		tempVal = arr[i];//保存一下待插入的元素
		j = i - 1;
		while (j >= 0 && tempVal < arr[j])
		{
			arr[j + 1] = arr[j];
			--j;
		}
		arr[j + 1] = tempVal;//把保存的元素放在對應的位置
	}

希爾
插入的優化
按間隔分組,間隔越小分組越少
把小的數往前集合,大的數往後,一定概率減少後續插入比較次數

void shell_sort(int arr[], size_t len)
{
	int tempVal;
	int j;
	int jump = len >> 1;
	while (jump != 0)
	{
		for (int i = jump; i < len; ++i)//確定插入過程中需要插入元素的下標用i表示
		{
			tempVal = arr[i];//保存一下待插入的元素
			j = i - jump;
			while (j >= 0 && tempVal < arr[j])
			{
				arr[j + jump] = arr[j];
				j -= jump;
			}
			arr[j + jump] = tempVal;//把保存的元素放在對應的位置
		}
		jump >>= 1;
	}
}

桶排序
行與取餘的數對應,列與位置對應
快但浪費空間,不需要比較

void radix_sort(int arr[], size_t len)
{
	int temp[10][10] = {};
//對不同位數整除都會得到一個排序後的序列,需要根據容器內最大的值設置位數,以得到正確的排序結果,並且要逐位排序
	for (int n = 1; n < 1000; n *= 10)
	{
		for (int x = 0; x < 10; ++x)
		{
			for (int y = 0; y < 10; ++y)
			{
				temp[x][y] = -1;//不一定是-1
			}
		}

		for (int i = 0; i < len; ++i)
		{
			int tempIndex = (arr[i] / n) % 10;
			temp[tempIndex][i] = arr[i];
		}

		int k = 0;
		for (int x = 0; x < 10; ++x)
		{
			for (int y = 0; y < 10; ++y)
			{
				if (temp[x][y] != -1)
				{
					arr[k++] = temp[x][y];
				}
			}
		}
	}
}

歸併
速度和希爾差不多,用到遞歸,需要輔助空間

void _merge_in_arr(int arr[], int left, int mid, int right)//用於處理合並
{
	//準備一個輔助數組
	int length = right - left + 1;//表示輔助數組的長度
	int *pData = new int[length];
	//memset 內存逐字節賦值,第一個參數是哪個內存,第二個參數賦什麼值,第三個參數這個內存需要賦多大的內存
	memset(pData, 0, sizeof(int)* length);

	//合併
	int low = left;//定義一個變量接一下左邊第一個下標位置
	int hig = mid + 1;//定義一個變量接一下右邊區間的第一個下標位置
	int index = 0;//給輔助數組遍歷的下標 

	while (hig <= right && low <= mid)//左右區間都沒有比較完,都有數據
	{
		while (low <= mid && arr[low] <= arr[hig])//如果左邊區間沒有越界,並且左區間的數值<=右區間的數值
		{
			pData[index++] = arr[low++];
		}
		while (hig <= right && arr[low] > arr[hig])//如果右邊區間沒有越界,並且左區間的數值>右區間的數值
		{
			pData[index++] = arr[hig++];
		}
	}
	
	//到這一步,證明起碼有一個區間是合併進了輔助數組
	if (hig <= right)//證明右區間並沒有完成合並,左區間是完成合並,把右區間剩下的數據直接拷貝到輔助數組即可
		memcpy(&pData[index],&arr[hig],sizeof(int) * (right - hig + 1));//內存拷貝,有3個參數,表示把第二個參數的首地址裏面的內容拷貝到第一個參數表示的首地址裏面,拷貝大小爲第三個參數表示的大小
	if (low <= mid)
		memcpy(&pData[index], &arr[low], sizeof(int)* (mid - low + 1));

	memcpy(&arr[left], pData, sizeof(int)* length);
	delete[] pData;
}

void _merge(int arr[], int left, int right)//通過遞歸把數組拆成兩個部分
{
	if (left >= right)//當左和右下標一致的時候,證明這個區間只有一個元素,不用再拆
		return;
	int mid = ((right - left) >> 1) + left;
	_merge(arr, left, mid);//遞歸左區間
	_merge(arr, mid + 1, right);//遞歸右區間

	//合併操作
	_merge_in_arr(arr, left, mid, right);
}

//歸併
void merge_sort(int arr[],size_t len)
{
	_merge(arr, 0, len - 1);
}

快速
先確定元素位置
不用<=或者>=會導致不穩定

void quick_sort(int arr[], int low, int hight)
{
	int t = arr[low];//確定標杆的值
	int f = low + 1;//表示指的數應該比標杆小
	int b = hight;//表示指的數應該比標杆大

	if (low >= hight) return;//表示只有一個元素,無需定位
	int tempVal;
	while (f <= b)//表示待定位的區間是存在的
	{
		while (f <= b && arr[f] <= t) f++;//一直找比標杆大的元素
		while (f <= b && arr[b] >= t) b--;//一直找比標杆小的元素
		if (f < b)//定位區間沒有搜索完成
		{
			tempVal = arr[f];
			arr[f] = arr[b];
			arr[b] = tempVal;
			f++;
			b--;
		}
	}
	arr[low] = arr[b];
	arr[b] = t;
	quick_sort(arr, low, b - 1);
	quick_sort(arr, b + 1, hight);
}

二分查找

int binarySearch(int arr[], int low, int hight, int findVal)
{
	int mid = 0;//表示中間下標
	while (low <= hight)//表示區間存在
	{
		mid = ((hight - low) >> 1) + low;
		if (findVal == arr[mid])
			return mid;
		if (findVal < arr[mid])
			hight = mid - 1;
		if (findVal > arr[mid])
			low = mid + 1;
	}
	return -1;
}
發佈了52 篇原創文章 · 獲贊 5 · 訪問量 4422
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章