排序问题

来源:互联网 发布:miui9怎么卸载软件 编辑:程序博客网 时间:2024/06/07 04:04

reference
http://blog.csdn.net/acm_1361677193/article/details/48206603

这里写图片描述
思想/例子
【冒泡】一种交换排序1,它的基本思想是:两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止。http://blog.csdn.net/lemon_tree12138/article/details/50591859

这里写图片描述
这里写图片描述
【鸡尾酒 双向冒泡】
这里写图片描述
【插入】 常见的插入排序有插入排序(Insertion Sort),希尔排序(Shell Sort),二叉查找树排序(Tree Sort),图书馆排序(Library Sort),Patience排序(Patience Sort)

void SelectSort(int *a, int len){    for (int i=0; i<len-1; i++)    {        int k = i;        int key = a[i];        for (int j=i+1; j<len; j++)        {            if (a[j]<key)            {                k = j;                key = a[j];            }        }        if (k!=i)            swap(a[i], a[k]);    }}//直接插入排序:将一个记录插入到已经排好序的有序表中,得到新的有序表

【归并】

#include <iostream>using namespace std;/*归并过程--将两个有序数组合并成一个有序数组*/void merge(int array[],int tempArray[],int left,int right,int middle){    int index1=left;    int index2=middle+1;    for(int i=left;(index1<=middle)&&(index2<=right);i++)    {        if(array[index1]<array[index2])            tempArray[i]=array[index1++];        else            tempArray[i]=array[index2++];    }    while(index1<=middle)        tempArray[i++]=array[index1++];    while(index2<=right)        tempArray[i++]=array[index2++];    for(i=left;i<=right;i++)        array[i]=tempArray[i];  }/*两路归并排序--array[]为待排数组,tempArray[]为临时数组,leftright分别是数组两端*/void mergeSort(int array[],int tempArray[],int left,int right){    if(left<right)    {        int middle=(left+right)/2;        mergeSort(array,tempArray,left,middle);        mergeSort(array,tempArray,middle+1,right);        merge(array,tempArray,left,right,middle);    }}int main(){    int array[8]={6,8,7,3,1,2,5,4};    int tempArray[8];    mergeSort(array,tempArray,0,7);    for(int i=0;i<8;i++)        cout<<array[i]<<"  ";    cout<<endl;    return 0;}

【桶】

#include <iostream>using namespace std;/*归并过程--将两个有序数组合并成一个有序数组*/void merge(int array[],int tempArray[],int left,int right,int middle){    int index1=left;    int index2=middle+1;    for(int i=left;(index1<=middle)&&(index2<=right);i++)    {        if(array[index1]<array[index2])            tempArray[i]=array[index1++];        else            tempArray[i]=array[index2++];    }    while(index1<=middle)        tempArray[i++]=array[index1++];    while(index2<=right)        tempArray[i++]=array[index2++];    for(i=left;i<=right;i++)        array[i]=tempArray[i];  }/*两路归并排序--array[]为待排数组,tempArray[]为临时数组,leftright分别是数组两端*/void mergeSort(int array[],int tempArray[],int left,int right){    if(left<right)    {        int middle=(left+right)/2;        mergeSort(array,tempArray,left,middle);        mergeSort(array,tempArray,middle+1,right);        merge(array,tempArray,left,right,middle);    }}int main(){    int array[8]={6,8,7,3,1,2,5,4};    int tempArray[8];    mergeSort(array,tempArray,0,7);    for(int i=0;i<8;i++)        cout<<array[i]<<"  ";    cout<<endl;    return 0;}

【基数】

/* * Get the spcific digit of given number. * For example, number 234,  *  the 0st digit is 4,  *  the 1st digit is 3, *  the 2nd digit is 2, *  the 3th digit is 0. */int GetNDigit(int nNumber, int nIdx){    for (int i = nIdx; i > 0; i--) {        nNumber /= 10;    }    return nNumber % 10;}/* * Counting Sort the given array according to specific digit. * array: 待排序数组. * nLength: 待排序数组长度 * nIdxDigit: 排序要依据的位. 0为最低位,高位依次加1. * nK: *nIdxDigit位上可能出现的最大数字(对10进制数排序则nK=9). */void CountingSort_SpecificDigit(int array[], size_t nLength, int nIdxDigit, int nK=9){    if (NULL == array || 0 == nLength || 0 == nK)        return;    int *digitNum = new int[nLength];    memset(digitNum, 0, sizeof(int)*nLength);    int *count = new int[nK+1];    memset(count, 0, sizeof(int)*(nK+1));    int *arrayResult = new int[nLength];    memset(arrayResult, 0, sizeof(int)*nLength);    // 数组digitNum[],保存每个元素指定位上的数字,作为排序依据    for (int idx = 0; idx<nLength; idx++)        digitNum[idx] = GetNDigit(array[idx], nIdxDigit);    // 先计数,count[idx]为值等于idx的元素的个数    for (int idx = 0; idx<nLength; idx++)        count[digitNum[idx]]++;    // 再累加,count[idx]为小于等于idx的元素的个数    for (int idx = 1; idx<nK+1; idx++)        count[idx] = count[idx] + count[idx-1];    // 从后向前循环(保证排序稳定), 根据指定位的数字大小    // 将array[idx]排在所有小于等于array[idx]的数(共count[digitNum[idx]]个)的后面    for (int idx=nLength-1; idx>=0; idx--)        {        arrayResult[count[digitNum[idx]]-1] = array[idx];        count[digitNum[idx]]--;        }    // 把排序结果写回原数组    memcpy(array, arrayResult, sizeof(int)*nLength);    delete [] digitNum;    delete [] count;    delete [] arrayResult;}/* * 基数排序 * array: 待排序数组 * nLength: 待排序数组元素个数 * nDigit: 所有元素的最大位数 */void RadixSort(int array[], size_t nLength, int nDigit){    // 从最低位到最高位,依次调用计数排序    for (int idx=0; idx<=nDigit; idx++) {        CountingSort_SpecificDigit(array, nLength, idx);    }}

【二叉树】

#pragma once#include<iostream>using namespace std;//树节点定义,包含父节点指针(便于回溯前驱与后继)typedef struct Node {    int data;    struct Node *leftchild;    struct Node *rightchild;    struct Node *parent;}Node_t;/*二叉排序树类定义*/class BSearchTree{ public:    BSearchTree(void);      ~BSearchTree(void);    inline Node_t* getRoot() const { return this->root;}     void createBSTree(int *dataset, int size); //建立二叉排序树    bool insertNode(Node_t **root, int value); //插入新节点,需要传入二级指针(改变根指针的值)    void inorderTraverse(Node_t *root) const;  //中序遍历    void visitMiddleOrder() const;  //对上一函数继续封装    Node_t* searchNode(Node_t *root,int value) const; //按值查找    void searchByValue(int value) const; //对上一函数继续封装    //最大与最小代码对称    void getMax(Node_t *root) const; //获取最大值    void getMin(Node_t *root) const; //获取最小值    //前驱与后继代码对称    void getPredecessor(Node_t *node); //获取节点前驱     void getSuccessor(Node_t *node); //获取节点后继    int getHeight(Node_t *root) const; //返回树高 private:     Node_t *root; //根节点};成员函数的实现:#include "BSearchTree.h"BSearchTree::BSearchTree(void){    root = NULL;}BSearchTree::~BSearchTree(void){    //to do sth}//建立二叉排序树(导入数组内元素,逐一插入)void BSearchTree:: createBSTree(int *dataset, int size) {    for ( int i=0; i<size; i++ ) {        insertNode(&root,dataset[i]);    }}//插入新节点//注意因为要修改root根指针的值,所以需要传入二级指针bool BSearchTree:: insertNode(Node_t **root, int value) {    //初始化将插入的新节点    Node_t *new_node = new Node_t;    if ( new_node == NULL ) {        return false;       }    new_node->data = value;    new_node->leftchild = new_node->rightchild = new_node->parent = NULL;     //空树时,直接让根指针指向新节点    if( (*root) == NULL ) {        *root = new_node;        return true;    }     //插入到当前结点(*root)的左孩子      if ((*root)->leftchild == NULL && (*root)->data > value ) {        new_node->parent = (*root);        (*root)->leftchild = new_node;        return true;    }     //插入到当前结点(*root)的右孩子      if((*root)->rightchild == NULL && (*root)->data < value){          new_node->parent = (*root);          (*root)->rightchild = new_node;          return true;      }      //递归法插入新节点    if ( (*root)->data > value ) {  //新节点的值小于根节点,递归寻找左边空位        insertNode( &(*root)->leftchild,value);  //关键点    }    else if ( (*root)->data < value ) {  //新节点的值大于根节点,递归寻找右边空位        insertNode( &(*root)->rightchild,value);     } else {        return true;    }}//中序遍历void BSearchTree:: inorderTraverse(Node_t *root) const {    //递归出口    if ( root == NULL ) {        return;    }    inorderTraverse( root->leftchild );    cout<< root->data <<" ";    inorderTraverse( root->rightchild );}void BSearchTree::visitMiddleOrder() const {    inorderTraverse(this->root);}//按值查找,返回节点的地址Node_t* BSearchTree:: searchNode(Node_t *root,int value) const {    if ( root == NULL ) {        return NULL;    }    if ( root->data > value ) {        searchNode( root->leftchild,value);    }    else if ( root->data < value ) {        searchNode( root->rightchild,value);    } else {        return root;    }}void BSearchTree:: searchByValue(int value) const{    Node_t *p_findnode = this->searchNode(root,value);    if ( p_findnode == NULL ) {        cout<<"没有找到该节点"<<endl;    } else {        cout<< "该节点存在" <<endl;    }}//获取最大值void BSearchTree:: getMax(Node_t *root) const {    while( root->rightchild ) {        root = root->rightchild;    }    cout<<root->data<<endl;}//获取最小值void BSearchTree:: getMin(Node_t *root) const {    while( root->leftchild ) {        root = root->leftchild;    }    cout<<root->data<<endl;}//获取节点前驱void BSearchTree:: getPredecessor(Node_t *node) {    //节点如果有左子树,则其前驱节点是左子树的最大值    if ( node->leftchild != NULL ) {        return getMax( node->leftchild );    } else {        cout<<"(该点无左子树,开始回溯祖先...)"<<endl;    }    //如果没有右子树,则向上回溯,最顶层的祖先节点则是后继    Node_t *y = node->parent; //y首先指向该节点的父节点    while( y != NULL && node == y->leftchild ) {        node = y;        y = y->parent;    }    cout<<y->data;}//获取节点后继void BSearchTree:: getSuccessor(Node_t *node) {    //节点如果有右子树,则其后继节点是右子树的最小值    if ( node->rightchild != NULL ) {        return getMin( node->rightchild );    } else {        cout<<"(该点无右子树,开始回溯祖先...)"<<endl;    }    //如果没有右子树,则向上回溯,最顶层的祖先节点则是后继    Node_t *y = node->parent;    while( y != NULL && node == y->rightchild ) { //遇到第一个“拐角”回溯结束        node = y;  //节点向上爬一层        y = y->parent; //y也向上逐层回溯祖先    }    cout<<y->data;}//返回树高,树通用写法//ps:算法导论认为只有一个根节点时树高为0,我们常认为1int BSearchTree::getHeight(Node_t *root) const {    return root ?  max(getHeight(root->leftchild),getHeight(root->rightchild))+1 : -1;}

【图书馆】

【选择】

void SelectSort(int *a, int len){    for (int i=0; i<len-1; i++)    {        int k = i;        int key = a[i];        for (int j=i+1; j<len; j++)        {            if (a[j]<key)            {                k = j;                key = a[j];            }        }        if (k!=i)            swap(a[i], a[k]);    }}

【希尔】
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
【堆】

// 最大堆调整void MaxHeapify(int *a, int i, int heapSize){    int l = (i+1)*2-1;    int r = (i+1)*2;    int largest;    if (l<=heapSize && a[l]>a[i])        largest = l;    else        largest = i;    if (r<=heapSize && a[r]>a[largest])        largest = r;    if (largest!=i)    {        swap(a[i], a[largest]);        MaxHeapify(a, largest, heapSize);    }}// 创建最大堆void BuildMaxHeap(int *a, int len){    for (int i=len/2-1; i>=0; i--)    {        MaxHeapify(a, i, len-1);    }}// 堆排序void HeapSort(int *a, int len){    BuildMaxHeap(a, len);    for (int i=len-1; i>0; i--)    {        swap(a[0], a[i]);        MaxHeapify(a, 0, i-1);    }}

【快速】
(http://blog.csdn.net/acm_1361677193/article/details/48206603)
http://blog.sina.com.cn/s/blog_5c5bc9070100y4zv.html

void SelectSort(int *a, int len){    for (int i=0; i<len-1; i++)    {        int k = i;        int key = a[i];        for (int j=i+1; j<len; j++)        {            if (a[j]<key)            {                k = j;                key = a[j];            }        }        if (k!=i)            swap(a[i], a[k]);    }}
  • gpu排序
    【CUDA sample】
    快排 quickSort: Stream 递归深度
    双调排序 bitcoinSort
    归并排序mergeSort

    【CUDA libarary thrust】http://bbs.csdn.net/topics/390810280

#include <thrust/host_vector.h>#include <thrust/device_vector.h>#include <thrust/generate.h>#include <thrust/sort.h>#include <thrust/copy.h>#include <cstdlib>#define NUM_ELEM (1024 * 1024)int main(void){    thrust::host_vector<int> host_array(NUM_ELEM);    thrust::generate(host_array.begin(), host_array.end(), rand);    thrust::device_vector<int> device_array = host_array;    thrust::sort(device_array.begin(), device_array.end());    thrust::sort(host_array.begin(), host_array.end());    thrust::host_vector<int> host_array_sorted = device_array;    return 0;}
0 0
原创粉丝点击