C language to achieve insertion sort
One, direct insertion sort
1.1 Basic idea
Direct insertion sort is a simple insertion sort method. The basic idea is:
insert the records to be sorted into an ordered sequence that has been sorted one by one according to the size of the key code value, until all the records are inserted. , Get a new ordered sequence.
In practice, when we play poker, we use the idea of insertion sort
1.2 Code implementation
We first write the code that inserts sorting only one row, as shown in the figure below, assuming that the array [0,end] is already an ordered array , then the subscript of our element to be sorted is end+1 , the subscript (end +1) The element is stored in tmp, and then compared with a[end] . As long as tmp<a[end] , the element whose subscript is end is moved backward while end is moved left , moving backward is to make room for Insert tmp, until tmp does not meet the conditions, we stop the loop , insert tmp into the appropriate position end+1 .
In this way, the code for insertion sort can be written
int end=i; //有序数组最后一个元素的下标
int tmp = a[end + 1]; //待插入元素存入临时变量tmp
while (end >= 0)
{
if (tmp < a[end]) //如果待插入元素比end下标的元素小
{
a[end + 1] = a[end]; //1.end下标元素向后挪方便tmp的插入
--end; //2.end左移进行下一轮的比较
}
else //如果待插入元素大于或等于end下标的元素退出循环
{
break;
}
}
a[end + 1] = tmp; //将tmp插入到数组当中
The complete code only needs to move the end to achieve insertion sort. We default end=0, that is , the first element is ordered , then just let the end move backward, and let each element compare with the elements in the previous order. That's it, the starting condition of end is to start from 0, and the end is end=n-2, because when end=n-2, the index of the element to be sorted is n-1, that is, the index of the last element of the array , The interval of end is [0,n-2], usually we like to write this interval as left closed and right open, namely [0, n-1)
// 插入排序
void InsertSort(int* a, int n)
{
//默认第一个数已经是有序
for (int i = 0; i < n-1; ++i)
{
int end=i; //有序数组最后一个元素的下标
int tmp = a[end + 1]; //待插入元素存入临时变量tmp
while (end >= 0)
{
if (tmp < a[end]) //如果待插入元素比end下标的元素小
{
a[end + 1] = a[end]; //1.end下标元素向后挪方便tmp的插入
--end; //2.end左移进行下一轮的比较
}
else //如果待插入元素大于或等于end下标的元素退出循环
{
break;
}
}
a[end + 1] = tmp; //将tmp插入到数组当中
}
}
Test Results
//打印数组
void PrintArr(int* a, int n)
{
for (int i = 0; i < n; ++i)
{
printf("%d ", a[i]);
}
printf("\n");
}
void TestInsertSort()
{
int a[] = {
2,4,7,2,6,4,5,7,8,32,33,11 };
int n = sizeof(a) / sizeof(a[0]);
PrintArr(a, n);
InsertSort(a, n);
PrintArr(a, n);
}
int main()
{
TestInsertSort();
system("pause");
return 0;
}
1.3 Summary of Features
Summary of the characteristics of direct insertion sort:
- The closer the set of elements is to order, the more time efficient the direct insertion sorting algorithm is
- Time complexity: O(N^2)
- Space complexity: O(1), it is a stable sorting algorithm
- Stability: stable
Second, Hill sort
1.1 Basic idea
Hill sorting method is also called reduced increment method. The basic idea of Hill sorting method is:
first select an integer gap (usually gap=gap/3+1), divide the array to be sorted into gap groups , all elements with a distance of gap are placed in the same group , and each The elements within a group are sorted . Then, reselect an integer gap and repeat the above grouping and sorting work . When time =. 1 GAP , then performs direct insertion sort , to ensure that all elements of the ordered.
1.2 Code implementation
Similarly, we assume that the array length n=10, gap=gap/3+1, then we first write a set of sorting code
- gap=4, the array is divided into four groups, (9,7,3), (1,4,5), (2,8), (5,6), perform insertion sort on these four groups, and the result is (3,7,9), (1,4,5), (2,8), (5,6).
After mastering the process of sorting gap=4, let's write this sorting first.
First we define the variable end = 0 starts from the first element of array 9 , the next element is to be inserted tmp end + gap elements subscripted lower is 7, we can find the law, when the end element 4 go, 4 Marked as 5, then we can determine that the interval subscript of end is [0,5]. Usually we like to turn the interval on the right into an open interval. You can find that it happens to be [0,n-gap) . If you don’t believe it , You can continue to look at the analysis of steps 2, 3, so that we can write a set of sorting codes
gap = gap/3+1;
for (int i = 0; i < n - gap; ++i) //i从0开始到n-gap结束
{
int end = i;
int tmp = a[end + gap]; //每次增加gap的步长作为插入元素
while (end >= 0)
{
if (tmp < a[end]) //如果待插入元素比end下标的元素小
{
a[end + gap] = a[end]; //1.end下标元素向后挪方便tmp的插入,这里end挪动的步长是gap而不是1了
end -= gap; //2.end左移进行下一轮的比较,同理左移gap步长
}
else //如果待插入元素大于或等于end下标的元素退出循环
{
break;
}
a[end + gap] = tmp; //将tmp插入到数组当中
}
}
- gap=2, the array is divided into two groups, (3,2,7,8,9), (1,5,4,6,5), perform insertion sort on these two groups respectively, the result is (2,3 , 7, 8, 9), (1, 4, 5, 5, 6). In this step, you can also find that the interval of end is [0, 8), 8=n-gap=10-2
- gap=1, the array is divided into two groups, (3,2,7,8,9), (1,5,4,6,5), perform insertion sort on these two groups respectively, the result is (2,3 , 7, 8, 9), (1, 4, 5, 5, 6). In this step, you can also find that the interval of end is [0, 9), 9=n-gap=10-1, and this step also proves that the end condition of end in insertion sort is n-1=10-1=9
After understanding the steps of Hill sorting, we only need to write the loop code of gap from 4 to 2 and then to 1. This step is very simple, first define gap=n, and loop gap=gap/3+1 each time , The last +1 is to ensure that the gap can be equal to 1, which is to ensure that the array is in order .
// 希尔排序
void ShellSort(int* a, int n)
{
//1.gap>1时为预排序,让数列更接近有序
//2.gap=1为直接插入排序,保证有序
int gap = n;
while (gap > 1)
{
gap = gap / 3 + 1; //通常的
for (int i = 0; i < n - gap; ++i) //i从0开始到n-gap结束
{
int end = i;
int tmp = a[end + gap]; //每次增加gap的步长作为插入元素
while (end >= 0)
{
if (tmp < a[end]) //如果待插入元素比end下标的元素小
{
a[end + gap] = a[end]; //1.end下标元素向后挪方便tmp的插入,这里end挪动的不长是gap而不是1了
end -= gap; //2.end左移进行下一轮的比较,同理左移gap步长
}
else //如果待插入元素大于或等于end下标的元素退出循环
{
break;
}
a[end + gap] = tmp; //将tmp插入到数组当中
}
}
}
}
Test Results
void TestShellSort()
{
int a[] = {
2,4,7,2,6,4,5,7,8,32,33,11 };
int n = sizeof(a) / sizeof(a[0]);
PrintArr(a, n);
ShellSort(a, n);
PrintArr(a, n);
}
int main()
{
//TestInsertSort();
TestShellSort();
system("pause");
return 0;
}
1.3 Summary of Features
Summary of the features of Hill sorting:
- Hill sorting is an optimization of direct insertion sorting.
- When gap> 1, they are all pre-sorted, the purpose is to make the array closer to order. When gap == 1, the array is already close to order, so it will be very fast. In this way, as a whole, an optimized effect can be achieved. After we realize it, we can compare the performance test.
- The time complexity of Hill sorting is not easy to calculate, it needs to be deduced, and the average time complexity is derived: O(N 1.3—N 2)
- Stability: unstable