常用的内部排序算法

一、 实验目的
1.掌握常见的内部排序算法的思想及其适用条件。
2.掌握常见的内部排序算法的程序实现。
二、 实验内容及要求
输入一组关键字序列分别实现下列排序:
(1) 实现简单选择排序、直接插入排序和冒泡排序。
(2) 实现希尔排序算法。
(3) 实现快速排序算法。
(4) 实现堆排序算法。
(5) * 快速排序的非递归算法。
(6) * 实现折半插入排序。
(7) 在主函数中设计一个简单的菜单,分别测试上述算法。
(8) * 综合训练:采用几组不同数据测试各个排序算法的性能(比较次数和移动次数)。

SortsAlgorithm.h

#ifndef DACM_ZSN_SORTSALGORITHM_H
#define DACM_ZSN_SORTSALGORITHM_H

#define MAXSIZE 100 /*参加排序元素的最大个数*/
typedef  int  KeyType;
typedef int InfoType;
typedef struct {
    KeyType  key;
    InfoType  otherinfo;  // 其他字段
}RedType;
typedef struct
{
    RedType  r[MAXSIZE+1];
    int length; /*参加排序元素的实际个数*/
}SqList;
void Swap(KeyType &key1,KeyType &key2);
void SL_print(SqList SL);
void DataInput(SqList &SL);
void DataInput1(SqList &L,int *arr);
void DataInput2(SqList &SL);
void SelectSort(SqList &L);
void InsertSort(SqList &L);
void MidInsertSort(SqList &L);
void ShellInsert(SqList &L,int dk);
void ShellSort(SqList &L,int dk[],int t);
void Swap(KeyType &a,KeyType &b);
void BubbleSort(SqList &L);

int Partition2(SqList &L, int left, int right);
void QSort(SqList &L,int low,int high);
void QuickSort(SqList &L);

//void HeapAdjust(SqList &L,int s,int m);
//void CreatHeap(SqList &L);
void HeapSort(SqList &L);
void menu();
void q_sort_stack(SqList &L, int n);
int partition(SqList &L, int left, int right);
//void quicksort2(vector<Comparable> &vec,int low,int high)
#endif //DACM_ZSN_SORTSALGORITHM_H

SortsAlgorithm.cpp

#include "SortsAlgorithm.h"
#include<iostream>
#include<vector>
#include<stack>
#include<cstdlib>
#include<algorithm>
#include <time.h>

using namespace std;


void SL_print(SqList SL) {
    for (int i = 0; i < SL.length; i++) {
        printf("%3d", SL.r[i]);
    }
    printf("\n");
}

void DataInput2(SqList &SL) {
    printf("请输入需要排序的数据:\n");
    int A[100], j = 0;
    while (1) {
        scanf("%d", A + j);
        if (A[j] == -1)
            break;
        j++;
    }
    int i = 0;
    SL.length = j;
//    SL_Init(SL,j);
    while (i < SL.length) {
        SL.r[i].key = A[i];
        i++;
    }
}

void DataInput(SqList &SL) {
    printf("请输入需要排序的数据:\n");

    int A[10] = {9, 8, 5, 76, 13, 27, 9, 32, 2, 50};
    int i = 0;
    SL.length = 10;
    while (i < SL.length) {
        SL.r[i].key = A[i];
        i++;
    }
}
void DataInput1(SqList &L,int *array){
    L.length=10;
    for (int i = 0; i < L.length; ++i) {
        L.r[i].key=*(array+i);
    }
}
//简单选择排序
void SelectSort(SqList &L) {
    int min = 0;
    int n = L.length;
    for (int i = 0; i < n - 1; ++i) {
        min = i;
        for (int j = i + 1; j < n; ++j) {
            if (L.r[j].key < L.r[min].key) {
                min = j;
            }
        }
        if (i != min) {
            Swap(L.r[i].key, L.r[min].key);
        }
    }
}

//插入排序,从小到大排序,升序
void InsertSort(SqList &L) {
    int i, j;
    //24 66 94  2 15 74 28 51 22 18  2
    for (i = 2; i <= L.length; i++) {
        if (L.r[i].key < L.r[i - 1].key) {
            L.r[0] = L.r[i];//放到暂存位置
            L.r[i] = L.r[i - 1];
            for (j = i - 2; L.r[0].key < L.r[j].key; --j)
                L.r[j + 1] = L.r[j];
            L.r[j + 1] = L.r[0];
        }
    }
}

//折半查找 插入排序
void MidInsertSort(SqList &L) {
    int i, j, low, high, mid;
    for (i = 2; i <= L.length; i++) {
        L.r[0] = L.r[i];
        low = 1;
        high = i - 1;
        while (low <= high)//先通过二分查找找到待插入位置
        {
            mid = (low + high) / 2;
            if (L.r[mid].key > L.r[0].key)
                high = mid - 1;
            else
                low = mid + 1;
        }
        for (j = i - 1; j >= high + 1; --j)
            L.r[j + 1] = L.r[j];
        L.r[high + 1] = L.r[0];
    }
}

//希尔排序
void ShellInsert(SqList &L, int dk) {
    int j;
    for (int i = dk + 1; i < L.length; ++i) {
        if (L.r[i].key < L.r[i - dk].key) {
            L.r[0] = L.r[i];
            for (j = i - dk; j > 0 && L.r[0].key < L.r[j].key; j -= dk) {
                L.r[j + dk] = L.r[j];
            }
            L.r[j + dk] = L.r[0];
        }
    }
}

void ShellSort(SqList &L, int dk[], int t) {
    //按增量序列dt【0.。t-1】对顺序表L做t趟希尔排序
    for (int i = 0; i < t; ++i) {
        ShellInsert(L, dk[i]);
    }
}

//冒泡排序
void Swap(KeyType &a, KeyType &b) {
    KeyType tmp;
    tmp = a;
    a = b;
    b = tmp;
}

void BubbleSort(SqList &L) {
    int i, j;
    int flag = 1;
    int m = L.length;
    for (i = 0; i < m - 1; i++)//i最多访问到8
    {
        flag = 0;
        for (j = m - 1; j > i; j--)//把最小值就放在最前面
        {
            if (L.r[j - 1].key > L.r[j].key) {
                Swap(L.r[j - 1].key, L.r[j].key);
                flag = 1;
            }
        }
    }
}

//书上快排
int Partition2(SqList &L, int low, int high) {
    int pivotkey;
    L.r[0] = L.r[low];
    pivotkey = L.r[low].key;
    while (low < high) {
        while (low < high && L.r[high].key >= pivotkey)
            --high;
        L.r[low] = L.r[high];
        while (low < high && L.r[low].key <= pivotkey)
            ++low;
        L.r[high] = L.r[low];
    }
    L.r[low] = L.r[0];
    return low;
}

void QSort(SqList &L, int low, int high) {
    int pivotloc;
    if (low < high) {
        pivotloc = Partition2(L, low, high);
        QSort(L, low, pivotloc - 1);
        QSort(L, pivotloc + 1, high);
    }
}

void QuickSort(SqList &L) {
    QSort(L, 1, L.length);
}


//递归实现
//快速排序
int Partition(SqList &L, int left, int right) {
    int k, i;//k记录要放入比分割值小的数据的位置
    for (i = left, k = left; i < right; i++) {
        if (L.r[i].key < L.r[right].key) {
            Swap(L.r[k].key, L.r[i].key);
            k++;
        }
    }
    Swap(L.r[k].key, L.r[right].key);
    return k;
}

void QuickSort(SqList &L, int low, int high) {

    if (low < high) {
        int pivotpos = Partition(L, low, high);//分割点左边的元素都比分割点要小,右边的比分割点大
        QuickSort(L, low, pivotpos - 1);
        QuickSort(L, pivotpos + 1, high);
    }
}

//快速排序非递归
int partition(SqList &L, int left, int right)
{
    int pivot = L.r[left].key;
    while (left < right)
    {
        while (left < right && L.r[right].key >= pivot)
            right--;
        L.r[left] = L.r[right];
        while (left < right && L.r[left].key <= pivot)
            left++;
        L.r[right] = L.r[left];
    }
    L.r[left].key = pivot;
    return left;
}

void q_sort_stack(SqList &L, int n)
{
    int left = 0;
    int right = n - 1;
    stack<int> s;
    s.push(left);
    s.push(right);
    while(!s.empty())
    {
        right = s.top();
        s.pop();
        left = s.top();
        s.pop();
        int index = partition(L, left, right);
        if (index - 1 > left)
        {
            s.push(left);
            s.push(index - 1);
        }
        if (index + 1 < right)
        {
            s.push(index + 1);
            s.push(right);
        }
    }
}
//堆排序
//void HeapAdjust(SqList &L,int s,int m){
//    RedType rc=L.r[s];
//    int j;
//    for(j=2*s;j<=m;j*=2){
//        if (j<m&&L.r[j].key<L.r[j+1].key)
//            ++j;
//        if (rc.key>=L.r[j].key)
//            break;
//    }
//    L.r[s]=rc;
//}
//void CreatHeap(SqList &L){
//    int n=L.length;
//    int i;
//    for (i = n/2; i > 0; --i) {
//        HeapAdjust(L,i,n);
//    }
//}
//void HeapSort(SqList &L){
//    CreatHeap(L);
//    RedType x;
//    int i;
//    for (i = L.length; i>1;--i) {
//        x=L.r[1];
//        L.r[1]=L.r[i];
//        L.r[i]=x;
//        HeapAdjust(L,1,i-1);
//    }
//}
void AdjustDown(SqList &L, int k, int len) {
    int dad = k;
    int son = 2 * dad + 1; //左孩子下标
    while (son <= len) {
        if (son + 1 <= len && L.r[son].key < L.r[son + 1].key)//看下有没有右孩子,比较左右孩子选大的
        {
            son++;
        }
        if (L.r[son].key > L.r[dad].key)//比较孩子和父亲
        {
            Swap(L.r[son].key, L.r[dad].key);
            dad = son;
            son = 2 * dad + 1;
        } else {
            break;
        }
    }
}


void HeapSort(SqList &L) {
    int i;
    int len = L.length;
    //建立大顶堆
    for (i = len / 2; i >= 0; i--) {
        AdjustDown(L, i, len);
    }
    Swap(L.r[0].key, L.r[len].key);//交换顶部和数组最后一个元素
    for (i = len - 1; i > 0; i--) {
        AdjustDown(L, 0, i);//剩下元素调整为大根堆
        Swap(L.r[0].key, L.r[i].key);
    }
}

void menu() {
    printf("-------------------------------------\n");
    printf("\t选择\n");
    printf("1.简单选择排序\n");
    printf("2.直接插入排序\n");
    printf("3.冒泡排序\n");
    printf("4.希尔排序\n");
    printf("5.快速排序\n");
    printf("6.堆排序\n");
    printf("7.快速排序的非递归\n");
    printf("8.折半插入排序\n");
    printf("9.多组随机数测试\n");
    printf("0.退出\n");
    printf("-------------------------------------\n");
}

int main() {
    while (1) {
        SqList L;
//        printf("\n未排序数据为:\n");
//        DataInput(L);///////////
//        int a1,i;
//        srand((int)time(NULL));
//        int A[11]={49,38,65,97,76,13,27,1,32,2,5};
//        for (i = 0; i < 11; ++i) {
//            a1=rand();
//            int p=a1%(100-1+i)+1;
//            L.r[i].key=p;
//            L.r[i].key=A[i];
//        }
//        L.length=i+1;
//        L.length;
        DataInput(L);
//        DataInput2(L);
        SL_print(L);
        int dk[] = {1, 3, 5, 7, 9, 11, 13};
        menu();
        int choice = 0;
        scanf("%d", &choice);
        switch (choice) {
            case 1:
                SelectSort(L);
                SL_print(L);
                break;
            case 2://第一个无了
//                L.length-=1;
                InsertSort(L);
                SL_print(L);
                break;
            case 3:
                BubbleSort(L);
                SL_print(L);
                break;
            case 4:
                ShellSort(L, dk, 2);
                SL_print(L);
                break;
            case 5://第一个无了
                QuickSort(L);
//                QuickSort(L,1,L.length-1);
                SL_print(L);
                break;
            case 6://有问题
                HeapSort(L);
                SL_print(L);
                break;
            case 7://有问题
                //快速排序非递归
                q_sort_stack(L,L.length-1);
                SL_print(L);
                break;
            case 8://有问题
                MidInsertSort(L);
                SL_print(L);
                break;
            case 9:
                //其他多组数据测试
                int a,i,j;
                int arr[8][10];
                SqList SL[8];
                srand((int) time(NULL));
                printf("待测试数据\n");
                for (i = 0; i < 8; ++i) {
                    for (j = 0; j < 10; ++j) {
                        a = rand();
                        int p = a % (100 - 1 + j) + 1;
                        arr[i][j] = p;
                    }
                    DataInput1(SL[i],arr[i]);
                    SL_print(SL[i]);
                }
                printf("开始测试\n");
                SelectSort(SL[0]);
                SL_print(SL[0]);
                InsertSort(SL[1]);
                SL_print(SL[1]);
                MidInsertSort(SL[2]);
                SL_print(SL[2]);
//                ShellSort(SL[3]);
                BubbleSort(SL[3]);
                SL_print(SL[3]);
                QuickSort(SL[4]);
                SL_print(SL[4]);
                HeapSort(SL[5]);
                SL_print(SL[5]);
                q_sort_stack(SL[6],SL[6].length);
                SL_print(SL[6]);
                break;
            case 0:
                return 0;
        }
    }
}
posted @ 2022-06-30 14:14  WEIWEI1095  阅读(92)  评论(0)    收藏  举报
*/
作品集 //