/** * 书本:《算法分析与设计》 * 功能:给定线性序列集合中n个元素和一个整数k,1<=k<=n,输出者n个元素中第“k小”元素的值和位置 * 文件:lesson4.cpp * 时间:2014年11月16日13:41:04 * 作者:cutter_point */ #include <iostream> using namespace std; /* *1、实现这个算法首先肯定是要排序 *2、排好序之后第k个就是第k小的了 *3、再根据找出来的数据,回到原来的数组中找到原来的位置 */ void paiXu(int *a, int *b, int left, int right, int mid); //前向声明 //由于是吧b先排序排好,然后放回到a中,吧原来的数据覆盖所以得有一个吧b拷贝到a的过程 void copy(int *a, int *b, int left, int right) { for (int i = left; i <= right; ++i) { a[i] = b[i]; } } //使用合并排序对数组进行排序 void heBin(int *a, int left, int right) { int *b = new int[sizeof(a) / sizeof(*a)]; //首先这个算法至少得有两个元素吧 if (left < right) { *b = { 0 }; //去中点,一直取中点,直到剩下2个元素合并排序 int mid = (left + right) / 2; //对这两边进行排序合并 heBin(a, left, mid); heBin(a, mid + 1, right); /* cout<<endl; cout<<mid<<"--------------"<<endl; */ paiXu(a, b, left, right, mid); //最后一道paiXu出问题了!!解决:由于是吧b先排序排好,然后放回到a中,吧原来的数据覆盖所以得有一个吧b拷贝到a的过程 /* cout<<endl; for(int i = 0; i < 10 ; ++i) { cout<<b[i]<<' '; } */ copy(a, b, left, right); } } //这里有一个合并排序的核心算法 void paiXu(int a[], int *b, int left, int right, int mid) { int rb = mid + 1; //右边集合的开始 int i = left, j = left; //这个i和j一个是左边集合的起始,一个是b数组的计数器 while (i <= mid && rb <= right) //两边一起开始比较,合并排序,如果有一边满了,其余的直接按顺序拍下去就可以了 { if (a[i] <= a[rb]) //左边集合的数据依次和右边的数据比较 b[j++] = a[i++]; //把左边对应的数据先放到b中,然后向后推移一位 else b[j++] = a[rb++]; //把左边对应的数据先放到b中,然后向后推移一位 } //排序完成后剩下的继续 //如果是左边的排完了,把右边剩下的排完 if (i > mid) { for (int q = rb; q <= right; ++q) //把右边剩下的全部拍到后面去 b[j++] = a[q]; } else { //右边的排完了,把左边的剩下的排完 for (int q = i; q <= mid; ++q) b[j++] = a[q]; } } //排序完成后输出要输出的数据 //1、原来的数组 //2、排好序的数组 //3、输出相应的数值和位置 void show(int *a, int *b, int k, int n) { //a是原始数组,b是排好序的数组,k是要找的第k小的数,一共n个数 /* int xunZhao = 0; cout << "原来的数组是:" << endl; for (int a1 = 0; a1 < n; ++a1) { cout << a[a1] << ' '; } */ //输出新的数组 cout << endl << "排好序的数组是:" << endl; for (int a2 = 0; a2 < n; ++a2) { cout << a[a2] << ' '; } int xunZhao = 0; while (a[k - 1] != b[xunZhao]) { ++xunZhao; } cout << endl << "第 " << k << " 小的数是:" << a[k - 1] << " 原位置是:" << xunZhao + 1 << endl; } int main() { char c; int k, n; int a[] = { 1, 2, 4, 3, 7, 5, 6, 8, 9, 10 }; int b[] = { 1, 2, 4, 3, 7, 5, 6, 8, 9, 10 }; n = 10; cout << "原来的数组是:" << endl; for (int a1 = 0; a1 < n; ++a1) { cout << b[a1] << ' '; } while (true) { heBin(a, 0, 9); cout << endl << "你想知道第几小的数?" << endl; cin >> k; show(a, b, k, n); } return 0; }
原文地址:http://blog.csdn.net/cutter_point/article/details/41174993