稳定性: 相同值的位置在排序后发生变化 那就说明此排序算法的稳定性差。
直接插入排序的时间复杂度是O(n^2)
空间复杂度是O(1)。
直接插入排序:每次从带排排序序列中取出一个值,放到已经排序好的序列中,然后依次保持有序
二、希尔排序希尔排序:增效增量排序
原始数据:12 9 18 20 5 10 28 32 1 4 80 91 2 88 66
最小增量数组
(5, 3,1)注意最后一个增量必须为1。
从12向后数5**(增量为5)**,将10和12一个组。
第一组为12,10,80。
第二组为 9,28,91。
第三组为18,32,2。
第四组为20,1,88。
第五组为5,4,66。
每组依次排序,得到这个结果:
按增量3再进行排序:
最后按增量1进行排序:
此时排序完成。
直接插入越有序,排序越快,这也是希尔排序对插入排序优化的原因。
for循环的处理顺序:
希尔排序的时间空间复杂度:
时间复杂度为O(N^1.3~1.7)
空间复杂度是O(1)
因为存在跳跃交换所以稳定性较低。
#include#include #include void Merge_Sort(int* arr, int len, int gap) { int low1 = 0; int hign1 = low1 + gap - 1; int low2 = hign1 + 1; int hign2 = low2+gap-1 <=len-1 ? low2 + gap - 1 : len - 1; int k = 0; int* brr = (int*)malloc(sizeof(int) * 30); while (low2 < len) { while (low1 <= hign1 && low2 <= hign2) { if (arr[low1] > arr[low2]) { brr[k++] = arr[low2++]; } if (arr[low1] <= arr[low2]) { brr[k++] = arr[low1++]; } } //for(int i=0;i brr[k++] = arr[low1++]; } while (low2 <= hign2) { brr[k++] = arr[low2++]; } low1 = hign2 + 1; hign1 = low1 + gap - 1; low2 = hign1 + 1;//用low2确定右侧是否有数据的状态 hign2 = low2 + gap - 1 < len ? low2 + gap - 1 : len - 1; } while (low1 brr[k++] = arr[low1++]; } for (int i = 0; i < len; ++i) { arr[i] = brr[i]; } free(brr); } void Show(int* arr, int len) { for (int i = 0; i < len; i++) { printf("%4d", arr[i]); } } void Merge(int* arr, int len) { int gap = 0; for (int i = 1; i < len; i *= 2) { gap = i; Merge_Sort(arr,len,gap); } } int main() { int arr[] = { 8423,34,45,56,67,78,879,345,45,12,90,84,8,12 }; int len = sizeof(arr) / sizeof(arr[0]); Merge(arr, len); Show(arr, len); return 0; }
归并排序的时间空间复杂度:
时间复杂度为:O(nlogn)
空间复杂度为:O(n)
归并排序不存在跳跃交换,遂稳定。
四、快排
因为存在跳跃交换,所以属于不稳定的排序。
时间复杂度为平均nlogn,空间复杂度为logn,理由是如下函数 在递归实现时,函数没结束时,
一直在申请栈空间(变量par).
`void Quick(int* arr,int left,int right)
{
int par=Quick_Sort(arr, left, right);
if (par > left + 1)
{
Quick(arr, left, par - 1);
}
if (par
Quick(arr, par + 1,right);
}
}`
#include#include #include int Quick_Sort(int* arr, int left, int right) { int tmp = arr[left]; while(left while (left tmp) { right--; } if (right == left) { arr[right] = tmp; return right; } arr[left] = arr[right]; while (left < right && arr[left] <=tmp)// <=tmp 没加等号 { left++; } if (left == right) { arr[left] = tmp;//这两行代码换成BREAK也可以。 return left; } arr[right] = arr[left]; } arr[left] = tmp;//因为大循环的意思没领悟 所以这儿就没想清楚 return left; } void Quick(int* arr,int left,int right) { int par=Quick_Sort(arr, left, right); if (par > left + 1) { Quick(arr, left, par - 1); } if (par Quick(arr, par + 1,right); } } void Show(int* arr, int len) { for (int i = 0; i < len; i++) { printf("%d ", arr[i]); } printf("n"); } int main() { int arr[] = { 12,34,45,56,23,34,56,2,234,45,23,34,45,67,23 }; int len = sizeof(arr) / sizeof(arr[0]); Quick(arr,0,len-1); Show(arr, len); return 0; }
不用递归的代码实现
void Quick_Stack(int* arr, int left, int right)
{
std::stack st;
int par = Quick_Sort(arr, left, right);
if (par > left + 1)
{
//=Quick_Sort(arr, left, par - 1);
st.push(par - 1);
st.push(left);
}
if (par < right - 1)
{
//Quick_Sort(arr, par + 1, right);
st.push(right);
st.push(par + 1);
}
while (!st.empty())
{
left=st.top();
st.pop();
right = st.top();
st.pop();
par=Quick_Sort(arr,left,right);
if (par > left + 1)
{
//=Quick_Sort(arr, left, par - 1);
st.push(par - 1);
st.push(left);
}
if (par < right - 1)
{
//Quick_Sort(arr, par + 1, right);
st.push(right);
st.push(par + 1);
}
}
}
五、选择排序
void Select_Sort(int* arr, int len)
{
int left = 0;
int min = 0;
int tmp = 0;
while (left < len - 1)
{
min = left;
for (int i = left; i < len; i++)
{
if (arr[i] < arr[min])
{
//tmp = min;
min = i;
}
}
tmp = arr[left];
arr[left] = arr[min];
arr[min] = tmp;
left++;
}
}
void Show(int* arr, int len)
{
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
printf("n");
}
int main()
{
int arr[] = { 12,2,34,4,32,44,3,23,34,89 };
int len = sizeof(arr) / sizeof(arr[0]);
Select_Sort(arr, len);
Show(arr, len);
return 0;
}
六、基数排序选择排序的时间空间复杂度:
时间复杂度:O(n^2)
空间复杂度:O(1)
不稳定
时间复杂度为O(dn)
空间复杂度为O(dn)
稳定性:稳定
int Count = 0;
void Show(int* arr, int len)
{
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
printf("n");
}
int Get_bit(int* arr, int len)
{
int i = 0;
int max = 0;
while (i < len)
{
if (arr[i] > max)
{
max = arr[i];
}
i++;
}
while (max / 10 != 0)
{
max /= 10;
Count++;
}
Count++;
//for (int j = 0; j < Count; ++j)
//{
// Classify(arr, len);
//}
return Count;
}
int Gey_remainder(int n, int fin)
{
for (int i = 0; i < fin; ++i)
{
n /= 10;
}
return n % 10;
}
void Classify(int* arr, int len,int fin)
{
std::queue bucket[10];
for (int i = 0; i < len; i++)
{
int index = Get_remainder(arr[i], fin);
bucket[index].push(arr[i]);
}
int k = 0;
for (int i = 0; i <= 9; i++)
{
while (!bucket[i].empty()) //不能取一个就拉倒了,都得取走。
{
arr[k++] = bucket[i].front(); //1.一个筒子值都取完再取下一个筒子。
bucket[i].pop();
}
}
}
void redix_sort(int* arr, int len)
{
int fin=Get_bit(arr, len);
for (int i = 0; i < fin; ++i)
{
Classify(arr, len,i); //i控制个位十位百位取余,控制趟数。
}
}
int main()
{
int arr[] = { 12,2,34657,23456,23,5,80,232,56,89,3,23,34,89 };
int len = sizeof(arr) / sizeof(arr[0]);
redix_sort(arr, len);
Show(arr, len);
return 0;
}



