#include "stdafx.h"
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
void setArray(int *arr, int len) {
srand(time(nullptr));
for (int i = 0; i < len; ++i)
arr[i] = rand() % 101;
}
void print(int *arr, int len) {
for (int i = 0; i < len; ++i)
cout << arr[i] << " ";
cout << endl;
}
void ShellSort(int *arr, int len) {
for (int gap = len / 2; gap > 0; gap /= 2) {
for (int i = gap; i < len; ++i) {
int key = arr[i];
int j = i - gap;
while (j >= 0 && arr[j] > arr[i]) {
arr[j + gap] = arr[j];
j -= gap;
}
arr[j + gap] = key;
}
}
}
void InsertSort(int *arr, int len) {
for (int i = 1; i < len; ++i) {
int j = i - 1;
int key = arr[i];
while (arr[j] > key && j >= 0) {
arr[j + 1] = arr[j];
--j;
}
arr[j + 1] = key;
}
}
void BinaryInsertionSort(int *arr, int len) {
for (int i = 1; i < len; ++i) {
int key = arr[i];
int left = 0, right = i - 1, mid;
while (left <= right) {
mid = (left + right) / 2;
if (arr[mid] <= key)
left = mid + 1;
else
right = mid - 1;
}
for (int j = i; j > left; --j)
arr[j] = arr[j - 1];
arr[left] = key;
}
}
void merge(int *arr, int p, int q, int r) {
int n1 = q - p + 1;
int n2 = r - q;
int *left = new int[n1];
int *right = new int[n2];
for (int i = 0; i < n1; ++i)
left[i] = arr[p + i];
for (int i = 0; i < n2; ++i)
right[i] = arr[q + 1 + i];
int k = p, i = 0, j = 0;
while (i < n1 || j < n2) {
if (i == n1)
arr[k++] = right[j++];
else if (j == n2)
arr[k++] = left[i++];
else {
if (left[i] < right[j])
arr[k++] = left[i++];
else
arr[k++] = right[j++];
}
}
delete[] left;
delete[] right;
}
void mergeSort(int *arr, int p, int r) {
if (p < r) {
int q = (p + r) / 2;
mergeSort(arr, p, q);
mergeSort(arr, q + 1, r);
merge(arr, p, q, r);
}
}
int main()
{
srand(time(nullptr));
int arr[20];
const int len = 20;
setArray(arr, len);
cout << "排序前:\n";
print(arr, len);
cout << "直接插入排序:" << endl;
InsertSort(arr, len);
print(arr, len);
setArray(arr, len);
cout << "排序前:" << endl;
print(arr, len);
BinaryInsertionSort(arr, len);
cout << "折半插入排序后:" << endl;
print(arr, len);
setArray(arr, len);
cout << "排序前:" << endl;
print(arr, len);
mergeSort(arr, 0, len - 1);
cout << "归并排序后:" << endl;
print(arr, len);
setArray(arr, len);
cout << "排序前:" << endl;
print(arr, len);
ShellSort(arr, len);
cout << "希尔排序" << endl;
print(arr, len);
return 0;
}
/***************************************************
> 课后题2 - 5 逆序对问题
> 思路1:使用归并排序解,在两个子数组开始合并的时候,
如在[ [1 , 3 , 5 ] ,[2 ,4 , 6 ] ] 开始合并的时候
其中3和2组成了一个逆序对,那么3后面的每一个元素都将会跟2组成一个逆序对
由此便可算得数组中的总逆序对
> 思路2:直接使用冒泡排序
****************************************************/
#include "stdafx.h"
#include <iostream>
using namespace std;
int merge(int *arr, int p, int q, int r) {
int n1 = q - p + 1;
int n2 = r - q;
int *left = new int[n1];
int *right = new int[n2];
for (int i = 0; i < n1; ++i)
left[i] = arr[p + i];
for (int i = 0; i < n2; ++i)
right[i] = arr[q + 1 + i];
int k = p, i = 0, j = 0;
int res = 0;
while (i < n1 || j < n2) {
if (i == n1)
arr[k++] = right[j++];
else if (j == n2)
arr[k++] = left[i++];
else {
if (left[i] <= right[j])
arr[k++] = left[i++];
else {
arr[k++] = right[j++];
res += n1 - i;
}
}
}
return res;
}
int mergesort(int *arr, int p, int r) {
int res = 0;
if (p < r) {
int q = (p + r) / 2;
res += mergesort(arr, p, q);
res += mergesort(arr, q + 1, r);
res += merge(arr, p, q, r);
}
return res;
}
/*******************************************************/
int bubbleSort(int *arr, int len) {
int res = 0;
for (int i =0;i<len;++i)
for (int j = len -1;j>i;--j)
if (arr[j - 1] > arr[j]) {
++res;
int temp = arr[j - 1];
arr[j - 1] = arr[j];
arr[j] = temp;
}
return res;
}
int main() {
int arr[] = { 2,3,8 ,6,1 };
cout << mergesort(arr, 0, 4) << endl;
int arr1[] = { 2,3,8,6,1 };
cout << bubbleSort(arr1, 4 + 1) << endl;
return 0;
}