数组排序(插入、选择、希尔、堆、归并、快速、冒泡)

插入排序如下,详细说明见注释:

void InsertSort(int A[], int N) {
    int P, j, tmp; //P为待插入元素的下标,j为待插入元素应该插入的位置, tmp用来保存待插入元素的数值
    for (P=1; P<N; P++) {
        tmp = A[P];
        for (j=P; j>0&&A[j-1]>tmp; j--) { //搜索待插入元素,应该插入的位置。注意A[j]=A[j-1]这种trick
            A[j]=A[j-1];
        }
        A[j]=tmp;
    }
}
选择排序如下:

void swap(int& a, int& b) { //注意,这里是引用
    if(a!=b) {
        a^=b;
        b^=a;
        a^=b;
    }
}

void SelectSort(int A[], int N) {
    int i, j, minIndex; //i代表第i+1小的元素应该放的index
    for (i=0; i<N-1; i++) {
        minIndex = i; //minIndex初始化为i
        for (j=i+1; j<N; j++) {
            if (A[j]<A[minIndex]) {
                minIndex=j; //如果A[j]<A[minIndex],则更新minIndex
            }
        }
        if (minIndex!=i) {
            swap(A[i], A[minIndex]);
        }
    }
}
希尔排序如下:

void shellSort(int A[], int N) {
    int increment, i, j, tmp;
    for (increment=N/2; increment>0; increment/=2) { //增量一定>0,增量初始化为N/2。
        for (i=increment; i<N; i++) {
            tmp=A[i];//tmp为第i个元素
            for (j=i; j>=increment; j-=increment) { //为tmp找到应该插入的位置
                if (A[j-increment]>tmp) {
                    A[j]=A[j-increment];
                } else {
                    break;
                }
            }
            A[j]=tmp; //在j位置插入tmp
            
        }
    }
}

堆排序如下:

#define leftChild(i) (2*(i)+1) //定义左孩子 宏
void percDown(int A[], int i, int N) {
    int tmp, child;
    for (tmp=A[i]; leftChild(i)<N; i=child) {
        child=leftChild(i);
        if (child!=N-1&&A[child+1]>A[child]) { //child表明左孩子大还是右孩子大
            child++;
        }
        if (A[child]>tmp) { //如果父亲元素小于大孩子,则父亲元素更新为大孩子元素
            A[i]=A[child];
        } else {
            break; //如果父亲元素大于等于大孩子元素,则跳出for循环
        }
    }
    A[i]=tmp; //i位置为tmp应该放置的位置
}
void heapSort(int A[], int N) {
    int i;
    for (i=N/2; i>=0; i--) { //自底向上建立最大堆,最大堆对应升序排序
        percDown(A, i, N); //自顶向下调整节点i
    }
    for (i=N-1; i>0; i--) {
        swap(A[0], A[i]); //删除最大元素
        percDown(A, 0, i); //自顶向下调整节点0的位置
    }
}

归并排序为:

void merge(int A[], int tmpArray[], int lpos, int rpos, int rend) { //lpos为左半部分的开始,rpos为右半部分的开始
    int i, lend = rpos-1, numElements = rend-lpos+1, tmpPos=lpos;
    while (lpos<=lend&&rpos<=rend) {
        if (A[lpos]<=A[rpos]) {
            tmpArray[tmpPos++]=A[lpos++];
        } else {
            tmpArray[tmpPos++]=A[rpos++];
        }
    }
    while (lpos<=lend) { //拷贝左半部分剩下的数
        tmpArray[tmpPos++]=A[lpos++];
    }
    while (rpos<=rend) { //拷贝右半部分剩下的数
        tmpArray[tmpPos++]=A[rpos++];
    }
    for (i=numElements; i>0; i--, rend--) { //把临时数组里面的数拷贝回原数组
        A[rend]=tmpArray[rend];
    }
}
void mSort(int A[], int tmpArray[], int left, int right) {
    int center;
    if(left<right) {
        center=(left+right)/2;
        mSort(A, tmpArray, left, center); //对左半部分进行排序
        mSort(A, tmpArray, center+1, right); //对右半部分进行排序
        merge(A, tmpArray, left, center+1, right); //合并结果
    }
}
void mergeSort(int A[], int N) {
    int* tmpArray;
    tmpArray = (int *)malloc(sizeof(int)*N); //开辟临时数组
    if(tmpArray != NULL) {
        mSort(A, tmpArray, 0, N-1);
        free(tmpArray);
    } else {
        printf("No space for tmp array !!!");
    }
    
}
快速排序如下:

#define cutoff 3
//返回left、center、right的中位数
int median3(int A[], int left, int right) {
    int center;
    center=(left+right)/2;
    if (A[left]>A[center]) {
        swap(A[left], A[center]);
    }
    if (A[left]>A[right]) {
        swap(A[left], A[right]);
    }
    
    if (A[center]>A[right]) {
        swap(A[center], A[right]);
    }
    //不等式A[left]<=A[center]<=A[right]成立
    swap(A[center], A[right-1]); //隐藏pivot
    return A[right-1]; //返回pivot
}
void qsort(int A[], int left, int right) {
    int i, j, pivot;
    if (left+cutoff<=right) { //元素个数>cutoff才用快排
        pivot=median3(A, left, right);
        i=left, j=right-1;
        for (; ; ) {
            while (++i<pivot) {}
            while (--j>pivot) {}
            if(i<j) {
                swap(A[i], A[j]);
            } else {
                break;
            }
        }
        swap(A[i], A[right-1]); //恢复pivot的位置
        qsort(A, left, i-1);
        qsort(A, i+1, right);
    } else {
        insertionSort(A+left, right-left+1);
    }
}
//快排的驱动程序
void quickSort(int A[], int N) {
    qsort(A, 0, N-1);
}

冒泡排序如下:

void bubbleSort(int A[], int N) {
    int i, j;
    for (i=N-1; i>0; i--) { //冒泡排序的核心思想就是,假如相邻元素A[j]>A[j+1],则交换这两个元素
        for (j=0; j<i; j++) {
            if (A[j]>A[j+1]) {
                swap(A[j], A[j+1]); //交换
            }
        }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值