【插入排序】直接,折半,二路,希尔

本文深入解析了四种排序算法:直接插入排序、折半插入排序、二路插入排序与希尔排序。通过具体代码实现,详细展示了每种算法的工作原理与实现过程,帮助读者理解不同排序算法的特点与应用场景。

插入排序 给出一下四种方法:


直接插入排序,折半插入排序,二路插入排序,希尔插入排序



代码实现:


#include<iostream>
using namespace std;
#define size 21

typedef int Sqlist[size];

void SInsertSort(Sqlist &L, int n)  //直接插入
{
	cout << "直接插入排序" << endl;

	for (int i = 2; i < n; ++i)
	{
		if (L[i] < L[i - 1])		//判断i与i-1位置的大小
		{
			L[0] = L[i];			//将i位置赋值给哨兵位

			int j;
			for (j = i - 1; L[0] < L[j]; --j)
			{
				L[j + 1] = L[j];		//循环后移
			}
			L[j + 1] = L[0];
		}
	}
}


void BInsertSort(Sqlist &L, int n)
{
	cout << "折半插入排序" << endl;
	for (int i = 2; i < n; ++i)
	{
		L[0] = L[i];

		int low = 1;
		int high = i - 1;
		int mid = 0;

		while (low <= high)
		{
			mid = (low + high) / 2;

			if (L[0] < L[mid])
			{
				high = mid - 1;
			}
			else
			{
				low = mid + 1;
			}
		}

		for (int j = i - 1; j >= high + 1; --j)
		{
			L[j + 1] = L[j];				//循环后移
		}
		L[high + 1] = L[0];
	}
}


void TWInsertSort(Sqlist &L, int n)			//2—路插入排序
{
	cout << "二路插入排序" << endl;

	Sqlist T;
	T[0] = L[0];
	int first;
	int last;
	first = last = 0;
	for (int i = 1; i < n; ++i)
	{
		if (L[i] < T[first])
		{
			first = (first - 1 + n) % n;
			T[first] = L[i];
		}
		else if (L[i] > T[last])
		{
			last++;
			T[last] = L[i];
		}
		else
		{
			last++;
			T[last] = T[last - 1];

			int j = last - 1;
			for (; L[i] < T[(j - 1 + n) % n]; j = (j - 1 + n) % n)
			{
				T[j] = T[(j - 1 + n) % n];
			}
			T[j] = L[i];
		}
	}
	for (int i = 0; i < n; ++i)
	{
		L[i] = T[first];
		first = (first + 1) % n;
	}
}




void ShellInsert(Sqlist &L, int n, int dk)//希尔插入  
{
	int t;
	for (int i = dk + 1; i <= n; ++i)         //按增量变化  
	{
		if (L[i] < L[i - dk])              //比较大小  
		{
			
			t = L[i];
			int j = i - dk;
			for (; j>0 && t<L[j]; j -= dk)  
			{
				L[j + dk] = L[j];
			}
			L[j + dk] = t;             //赋值  
		}
	}
}

void ShellSort(Sqlist &L, int n, int dlta[], int t)//希尔排序  
{
	for (int k = 0; k < t; ++k)                    //按照增量数组值重复插入排序  
	{
		ShellInsert(L, n, dlta[k]);
	}
}


void main()
{
	Sqlist sq = { 0, 49, 38, 65, 97, 76, 13, 27, 49 };//0为哨兵位
	
	
	cout << "原数组为:" << endl;
	for (int i = 1; i < 9; ++i)
	{
		cout << sq[i]<<' ';
	}
	cout << endl;


	SInsertSort(sq,9);

	for (int i = 1; i < 9; ++i)
	{
		cout << sq[i] << ' ';
	}
	cout << endl;

	BInsertSort(sq, 9);
	
	for (int i = 1; i < 9; ++i)
	{
		cout << sq[i] << ' ';
	}
	cout << endl;


	Sqlist Sq = { 49, 38, 65, 97, 76, 13, 27, 49 };
	
	cout << "原数组为:" << endl;
	for (int i = 0; i < 8; ++i)
	{
		cout << Sq[i]<<' ';
	}
	cout << endl;
	
	TWInsertSort(Sq, 8);

	for (int i = 0; i < 8; ++i)
	{
		cout << Sq[i] << ' ';
	}
	cout << endl;



	Sqlist sQ = { 0, 49, 38, 65, 97, 76, 13, 27, 49 };//哨兵位  
	cout << "原数组为:"<<endl;
	for (int i = 1; i <= 8; ++i)            //打印sQ
	{
		cout << sQ[i] << " ";
	}
	cout << endl;

	int dlta[] = { 5, 3, 1 };             //增量数组  

	ShellSort(sQ, 8, dlta, sizeof(dlta) / sizeof(int));//希尔排序

	cout << "希尔排序:" << endl;
	for (int j = 1; j <= 8; ++j)
	{
		cout << sQ[j] << " ";
	}
	cout << endl;
}

输出结果:



### C语言实现多种排序算法 #### 直接插入排序 直接插入排序是一种简单的排序方法,其基本操作是在已排序序列中找到合适的位置并插入新元素。 ```c void InsertionSort(int a[], int n) { int i, j; int current; for (i = 1; i &lt; n; ++i) { current = a[i]; j = i - 1; while (j >= 0 && a[j] > current) { a[j + 1] = a[j]; --j; } a[j + 1] = current; } } ``` #### 折半插入排序 折半插入排序通过减少比较次数来提高效率,在每次插入时利用二分查找确定插入位置。 ```c int BinarySearch(int a[], int low, int high, int key) { int mid; while (low &lt;= high) { mid = (low + high) / 2; if (key &lt; a[mid]) high = mid - 1; else low = mid + 1; } return low; } void BinaryInsertionSort(int a[], int n) { int i, location, j; int selected; for (i = 1; i &lt; n; ++i) { j = i - 1; selected = a[i]; // Find location where element should be inserted using binary search. location = BinarySearch(a, 0, j, selected); while (j >= location) { a[j + 1] = a[j]; --j; } a[j + 1] = selected; } } ``` #### 希尔排序 希尔排序是对直接插入排序的一种改进,它允许间隔较大的元素进行交换,从而加速整个过程。 ```c void ShellSort(int a[], int n) { int gap, i, j; int temp; for (gap = n / 2; gap > 0; gap /= 2) { for (i = gap; i &lt; n; ++i) { temp = a[i]; for (j = i; j >= gap && a[j - gap] > temp; j -= gap) { a[j] = a[j - gap]; } a[j] = temp; } } } ``` #### 冒泡排序 冒泡排序重复遍历列表,依次比较相邻两个元素,并按需交换它们的位置直到不再发生任何交换为止。 ```c void BubbleSort(int a[], int n) { bool swapped; int i, j; for (i = 0; i &lt; n - 1; ++i) { swapped = false; for (j = 0; j &lt; n - 1 - i; ++j) { if (a[j] > a[j + 1]) { swap(&a[j], &a[j + 1]); swapped = true; } } if (!swapped) break; } } ``` #### 快速排序 快速排序采用分治法策略,选择一个基准值将数组分为两部分,分别对这两部分继续执行相同的操作直至完全有序。 ```c void QuickSort(int a[], int left, int right) { if (left >= right) return; int pivotIndex = Partition(a, left, right); QuickSort(a, left, pivotIndex - 1); QuickSort(a, pivotIndex + 1, right); } int Partition(int a[], int left, int right) { int pivotValue = a[right]; int storeIndex = left; for (int i = left; i &lt; right; ++i) { if (a[i] &lt; pivotValue) { swap(&a[storeIndex++], &a[i]); } } swap(&a[right], &a[storeIndex]); return storeIndex; } ``` #### 简单选择排序 简单选择排序每一轮从未排序区域选出最小(最大)的一个记录放到已排序区间的末端。 ```c void SelectionSort(int a[], int n) { int minIdx; for (int i = 0; i &lt; n - 1; ++i) { minIdx = i; for (int j = i + 1; j &lt; n; ++j) { if (a[j] &lt; a[minIdx]) minIdx = j; } if (minIdx != i) swap(&a[minIdx], &a[i]); } } ``` #### 堆排序排序基于二叉堆数据结构,先构建最大堆再逐步取出堆顶元素形成有序序列。 ```c void Heapify(int arr[], int n, int i) { int largest = i; // Initialize largest as root int l = 2 * i + 1; // left child index int r = 2 * i + 2; // right child index // If left child is larger than root if (l &lt; n && arr[l] > arr[largest]) largest = l; // If right child is larger than largest so far if (r &lt; n && arr[r] > arr[largest]) largest = r; // If largest is not root if (largest != i) { swap(&arr[i], &arr[largest]); // Recursively heapify the affected sub-tree Heapify(arr, n, largest); } } void HeapSort(int arr[], int n) { // Build max heap for (int i = n / 2 - 1; i >= 0; i--) Heapify(arr, n, i); // Extract elements from heap one by one for (int i = n - 1; i >= 0; i--) { swap(&arr[0], &arr[i]); // Move current root to end Heapify(arr, i, 0); // call max heapify on reduced heap } } ``` #### 归并排序 归并排序也是一种典型的分治算法,递归地把当前区间分成两半,然后合并这两个已经排好序的部分得到完整的排序结果。 ```c void Merge(int array[], int const left, int const mid, int const right) { auto const subArrayOne = mid - left + 1; auto const subArrayTwo = right - mid; // Create temporary arrays auto* leftArray = new int[subArrayOne], *rightArray = new int[subArrayTwo]; // Copy data to temp arrays leftArray[] and rightArray[] for (auto i = 0; i &lt; subArrayOne; i++) leftArray[i] = array[left + i]; for (auto j = 0; j &lt; subArrayTwo; j++) rightArray[j] = array[mid + 1 + j]; auto indexOfSubArrayOne = 0, indexOfSubArrayTwo = 0; int indexOfMergedArray = left; // Merge the temp arrays back into array[left..right] while (indexOfSubArrayOne &lt; subArrayOne && indexOfSubArrayTwo &lt; subArrayTwo) { if (leftArray[indexOfSubArrayOne] &lt;= rightArray[indexOfSubArrayTwo]) { array[indexOfMergedArray] = leftArray[indexOfSubArrayOne++]; } else { array[indexOfMergedArray] = rightArray[indexOfSubArrayTwo++]; } indexOfMergedArray++; } // Copy remaining elements of leftArray[], if any while (indexOfSubArrayOne &lt; subArrayOne) { array[indexOfMergedArray++] = leftArray[indexOfSubArrayOne++]; } // Copy remaining elements of rightArray[], if any while (indexOfSubArrayTwo &lt; subArrayTwo) { array[indexOfMergedArray++] = rightArray[indexOfSubArrayTwo++]; } delete[] leftArray; delete[] rightArray; } void MergeSort(int array[], int const begin, int const end) { if (begin >= end) return; auto mid = begin + (end - begin) / 2; MergeSort(array, begin, mid); MergeSort(array, mid + 1, end); Merge(array, begin,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值