数据结构排序算法总结
直接插入排序,希尔排序,都是插入排序
希尔排序就不放代码了,希尔排序根据它的GAP是多少确定若干个子列,子列内部直接插入排序。,然后他们的
相对位置还是不变的,既是这个子列在总子列中是不变的
void zhijiecharu(int *a,int n){
int j=0;
for(int i=2;i<n-1;i++){
if(a[i]<a[i-1]){
a[0]=a[i];
for( j=i-1;a[0]<a[j];j--){
a[j+1]=a[j];
}
a[j+1]=a[0];
}
}
}
快速排序(交换排序)
找一个中枢轴,然后进行比较,比它小的数放左边,比它大的数放右边,完成后,该数组被分成两个部分再分别对两个部分进行排序,n可以证明, 函数quicksort的平均计算时间也是O(nlog2n)。实验结果表明**😗* 就平均计算时间而言**,** 快速排序是所有内排序方法中最好的一个。
写出第一趟快速排序结果是很重要的,就是有两个指针low和high,分别指向,如果i指向的元素大于pivot,则将给i元素放到j指向的元素上面来
代码我稍后放上来
使用“三者取中法”来选取枢轴记录,即:比较r(low).key、r(high).key和r( ).key,然后取三者之中关键字居中的那个记录作为枢轴。
冒泡排序(交换排序)
如果在冒泡排序代码中,里面一层循环在某次扫描中没有执行交换,则说明此时数组已经全部有序列,无需再扫描了。因此,增加一个标记,每次发生交换,就标记,如果某次循环完没有标记,则说明已经完成排序。
void BubbleSort_2(int a[], int size)
{
bool bSwaped = true;
for (int i = 0; i < size -1; i++)
{
// 每次先重置为false
bSwaped = false;
for (int j = size - 1; j > i ; j--)
{
if (a[j-1] > a[j])
{
int temp = a[j-1];
a[j-1] = a[j];
a[j] = temp;
bSwaped = true;
}
}
// 如果上一次扫描没有发生交换,则说明数组已经全部有序,退出循环
if (!bSwaped)
break;
}
}
简单选择排序
执行N-1次遍历,执行第I次把第i到N的最小元素放到第I个元素位置上
堆排序(选择排序)
堆的子树也要满足规律,上面的节点比下面的大;关键在于调整顶堆的关键步骤,建立堆的时候需要将数组从I到i/2来调整
void DownAdjust(int low, int high,int heap[])
{
int i = low, j = i * 2; // i 为欲调整结点,j 为其左孩子
while (j <= high)
{
if (j + 1 <= high && heap[j + 1] > heap[j]) j = j + 1; // 右孩子比左孩子大就让 j 保存右孩子下标
if (heap[j] <= heap[i]) break; // 如果孩子结点不大于父结点 i,就不用往下继续调整
swap(heap[j], heap[i]); // 否则交换最大的孩子与父结点 i 的结点值
i = j; // 较大的孩子结点作为新的欲调整结点,继续向下调整堆
j = i * 2;
}
}
// 构建大顶堆,从 n / 2 开始往1枚举即可
void CreatBigHeap(int n,int heap[])
{
for (int i = n / 2; i >= 1; --i)
DownAdjust(i, n,heap); // 左界为 i,右界为序列最后一个元素
}
void HeapSort(int heap[],int n)
{
for (int i = n; i > 1; --i) // 从堆尾结点开始枚举
{
swap(heap[i], heap[1]); // 交换堆顶和堆尾结点的值
DownAdjust(1, i - 1,heap); // 从堆顶开始向下调整
}
}
所有排序算法的时间,空间复杂度
[外链图片转存中...(img-kWNUR9gL-1709036388199)]
[外链图片转存中...(img-zOUFW6sv-1709036388199)]