标签:
1.归并排序
《算法导论》P19
参考网址:
白话经典算法系列之五 归并排序的实现 - MoreWindows Blog - 博客频道 - CSDN.NET
http://blog.csdn.net/morewindows/article/details/6678165
#include "stdafx.h" #include <iostream> using std::cout; #define ARRAY_LENGTH 11 //排序两个已经排好序的数组 //参数:data原始数组,copy组合成的数组,start,mid,end记录两个数组在原始数组中的位置 // mid表示第一个数组的截止位置 void Merge(int data[],int copy[],size_t start,size_t mid,size_t end) { //判断输入参数是否合法 if ((data != nullptr) && (copy != nullptr) && (start <= mid) && (mid < end)) { size_t i = start; //左数组开始位置 size_t j = mid + 1; //右数组开始位置 size_t index = start;//辅助数组开始位置 while ((i <= mid) && (j <= end)) { //比较两个值,较小者放入辅助数组中,并将指针前移 if (data[i] <= data[j]) { copy[index++] = data[i++]; } else { copy[index++] = data[j++]; } } //处理一个数组遍历完,另一个数组还有剩余元素的情况 while (i <= mid) { copy[index++] = data[i++]; } while (j<=end) { copy[index++] = data[j++]; } //整理排序好后的data数组 for (size_t k = 0; k <= end; k++) { data[k] = copy[k]; } } } //归并算法核心算法 void Merge_Sort(int data[], int copy[], size_t start, size_t end) { if ((data != nullptr) && (copy != nullptr)) { if ((start < end)) { size_t mid = (start + end) / 2; //分治思想 Merge_Sort(data, copy, start, mid); Merge_Sort(data, copy, mid + 1, end); //对数组进行排序 Merge(data, copy, start, mid, end); } } else { cout << "数组参数输入有误"; } } //打印数组 void printf_array(int data[], size_t length) { for (size_t i = 0; i < length; i++) { cout << data[i] << std::endl; } } int _tmain(int argc, _TCHAR* argv[]) { int data[] = {10,32,9,1,23,42,5,67,88,23,7}; //printf_array(data, ARRAY_LENGTH); int copy[ARRAY_LENGTH]; Merge_Sort(data, copy, 0, ARRAY_LENGTH - 1); printf_array(data, ARRAY_LENGTH); return 0; }
2.使用归并排序处理相关问题,统计数组中的逆序对
《剑指Offer》P191
// InversePais1.cpp : 计算N个元素的数组的逆序对 // #include "stdafx.h" //计算逆序对函数 int get_InversePairs(int data[],int copy[],size_t start,size_t mid,size_t end) { int count = 0; //判断数组是否为空,及输入的位置参数是否合法 if ((data!=nullptr)&&(copy!=nullptr)&&(start <= mid)&&(mid < end)) { int i = mid; int j = end; int index = end; while ((i >= start)&&(j >= mid + 1)&&(i * j >= 0)) { //比较取最大者,放在辅助数组的末位 if (data[i] > data[j]) { copy[index--] = data[i--]; count += (j - mid);//逆序对统计 } else { copy[index--] = data[j--]; //此时表示后者大于前者,不满足逆序对的定义,故count不进行操作 } } //处理剩余数组(注:此情况count也不再会发生改变,因为已经统计完全) while ((i >= start) && (i >= 0)) { copy[index--] = data[i--]; } while ((j >= mid + 1) && (j >= 0)) { copy[index--] = data[j--]; } printf("原始数据:"); for (size_t k = start; k <= end; k++) { printf("%d ", data[k]); } printf("\n当前数据:"); for (size_t k = start; k <= end; k++) { data[k] = copy[k]; printf("%d ", data[k]); } printf("\n"); printf("逆序对数:%d\n", count); } return count; } int Reverse_Pairs(int data[], int copy[], size_t start, size_t end) { if ((data == nullptr) || (copy == nullptr)) { return 0; } if (start >= end) { return 0; } //分治策略 int mid = (start + end) / 2; int left = Reverse_Pairs(data, copy, start, mid); int right = Reverse_Pairs(data, copy, mid + 1, end); int count = get_InversePairs(data, copy, start, mid, end); return left + right + count; } int _tmain(int argc, _TCHAR* argv[]) { int data[] = {7,5,6,4}; const size_t LENGTH = 4; int copy[LENGTH]; printf("%d\n", Reverse_Pairs(data, copy, 0, LENGTH-1)); return 0; }
标签:
原文地址:http://blog.csdn.net/woliuyunyicai/article/details/44171621