排序问题
来源:互联网 发布: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[]为临时数组,left和right分别是数组两端*/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[]为临时数组,left和right分别是数组两端*/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
- 排序问题-归并排序
- 排序问题-快速排序
- 【排序问题】选择排序
- 排序问题
- 排序 问题
- 排序问题
- 排序问题~~
- 排序问题
- 排序问题
- 排序问题
- 排序问题
- 排序问题
- 排序问题
- 排序 问题
- 排序问题
- 排序问题
- 排序问题
- 排序问题
- 深入理解ES7的async/await
- PHP中的的大括号(花括号{})使用详解
- 笔记-关于图片批量上传
- 字符串水题_CJ
- 51NOD算法马拉松 七星剑 【dp】
- 排序问题
- IntelliJ编译时,致命错误:在路径和启动路径中找不到包java.lang
- 关于Activity的生命周期与启动模式
- 设计模式_中介者模式下
- 欢迎使用CSDN-markdown编辑器
- DOM事件流之事件冒泡&事件捕获
- 数据结构-堆(Heap)
- QML静态值与属性绑定
- Servlet 3.0 文件上传