数据结构(C语言描述)—排序

1.排序分为内部排序和外部排序

内部排序:整个排序过程都在内存中进行

外部排序:由于排序的数据量大,需要依靠外部内存才能完成排序


2.排序的稳定性

在排序的过程中存在多个相同的关键字的纪录,若排序前关键字顺序和排序后关键字顺序一致,则称这种排序方法是稳定的,反之则不稳定。


 3.内部排序分类:(1)插入类排序 :在一个已排序好纪录子集基础上,每一步将下一个待排序的纪录有序插入到已经排好序的子集中,直到将所有待排序的纪录全部插入为止

在此算法思想上,插入排序又可以分为:直接插入排序,折半插入排序,希尔排序


直接插入排序是一种最基本的插入排序,基本思想是将第i个纪录插入到前面i-1个已经拍好序的纪录中,直接插入排序是从i=2开始的,默认是将第一个纪录视为已拍好序的单元子集合,

typedef int KeyType;
typedef struct {
    KeyType key;
    int data;
}RecordType;

//直接插入排序
void InsSort(RecordType r[],int length){
    for (int i = 2; i <= length; i++) {
        r[0] = r[i];int j = i - 1;//r[0] 备份待插入纪录
        while (r[0].key < r[j].key) {//与前面子集进行比对,如果小就将原来的数后移
            r[j+1] = r[j];
            j = j-1;
        }
        r[j+1] = r[0];
    }
}
折半插入排序:由于直接插入排序没有每次都要和前面的数进行一次比较,没有利用数据有序性这一特点,折半插入排序正是为了解决这一点,主要分为两步,第一步是查找插入点,第二步这是移动元素进行插入
 
 
void BinSort(RecordType r[],int length,RecordType e){
    int low = 0;
    int high = length-1;
    while (low <= high) {
        int middle = (low + high)/2;
        if (e.data < r[middle].data) {
            high = middle - 1;
        }
        if (e.data > r[middle].data) {
            low = middle + 1;
        }
    }
    for (int i = low; i<length; i++) {
        r[i+1] = r[i];
    }
    r[low] = e;
}
希尔排序:是冒泡排序的增强版,通过设定一个增量数组,每次对排列的数组进行分组,分组数月来越小,直至为1,这时算法退化为冒泡排序
 
 
 
 
/*一趟希尔排序*/
void ShellInsert(RecordType r[], int length,int delta){
    
    for (int i = 1+delta; i < length; i++) {
        if (r[i].key < r[i-delta].key) {
            r[0] = r[i];
            int j;
            for (j = i - delta; j >0&&r[0].key < r[j].key; j -= delta) {
                r[j+delta] = r[j];
            }
            r[j+delta]  = r[0];
        }
    }
}

void ShellSort(RecordType r[],int length,int delta[],int n){
    /*对纪录数组r做希尔排序,length为数组r的长度,delta为增量数组,n为delta数组的长度*/
    for (int i = 0; i <= n-1; ++i) {
        ShellInsert(r, length, delta[i]);
    }
}
 
 
快速排序:算法设定两个游标,前面一个后面一个,分别从两端向中间靠拢,前面游标将左边 比数组第一个数据大的筛到后面去,后面游标将比第一个数据小的筛到前面去,两个游标交叉进行,最后相遇相遇为止
 
 
int QKPass(RecordType r[],int left,int right){
    RecordType x = r[left];
    int low = left,high = right;
    while (low < high) {
        while (low < high && r[high].key >= x.key) {
            high -- ;
        }
        if (low < high) {
            r[low] = r[high];
            low ++;
        }
        while (low < high && r[low].key < x.key) {
            low ++;
        }
        if (low < high) {
            r[high] = r[low];
            ;
            high --;
        }
    }
    r[low] = x;
    return low;
}

void QKSort(RecordType r[],int low,int high){
    if (low < high) {
        int pos = QKPass(r, low, high);
        QKSort(r, low, pos - 1);
        QKSort(r, pos+1, high);
    }
}
冒泡排序:基本的交换类排序算法之一,通过比较相邻两个数大小交换位置,最后将最大的数据排到最后完成一次排序,下次排序将次大的数据排到倒数第二,依次下去,最后时限排好所有数据
 
 
void BubbleSort(RecordType r[],int length){
    int n = length;
    bool change = true;
    for (int i = 1; i<=n-1 && change; i ++) {
        change = false;
        for (int j = 0;j <= n - i; ++ j) { //i表示需要排几次
            if (r[j].key > r[j+1].key) {//j每一个i排序内做的交换
                RecordType temp = r[j];
                r[j] = r[j+1];
                r[j+1] = temp;
                change = true;
            }
        }
    }
}
简单选择排序:从数组第一个数开始,寻找数组中最小的数并将其插入,依次进行,最后实现排序
 
 
void SelectSort(RecordType r[],int length){
    int n = length;
    for (int i = 0; i <= n-1; i++) {
        int k = i;//k为最小值下表
        for (int j = i+1; j<=n-1; j++) {
            if (r[j].key <r[k].key) {
                k = j;
            }
        }
        if (k != i) { //最小值下标发生了改变
            RecordType temp = r[i];
            r[i] = r[k];
            r[k] = temp;
        }
    }
}
堆排序:数据按照堆结构存储

//调整堆
void sift(RecordType r[],int k,int m){
    RecordType t = r[k];
    KeyType x = r[k].key;
    int i = k;
    int j = 2*i;
    bool finish = false;
    while (j <= m && !finish) {
        if (j < m && r[j].key < r[j+1].key) {
            j = j+1;
        }
        if (x > r[j].key) {
            finish = true;
        }else{
            r[i] = r[j];
            i = j;
            j = 2*i;
        }
        
    }
    r[i] = t;
}
//建初堆
void crt_heap(RecordType r[],int length){
    int n = length;
    for (int i = n/2; i>=1; --i) {
        sift(r, i, n);
    }
}

void HeapSort(RecordType r[],int length){
    crt_heap(r, length);
    int n = length;
    for (int i = n; i >= 2; --i) {
        RecordType b = r[1];
        r[1] = r[i];
        r[i] = b;
        sift(r, 1, i-1);
    }
}


}


 
 

 
 

 
 
 
 


 
 
 
 
 
 
 
 
 
 
 
 




















猜你喜欢

转载自blog.csdn.net/u012149734/article/details/53780548