针对排序方法的学习总结:
排序方法中稳定与不稳定的是指待排序集合中存在多个相同关键字相同的数据元素,经过排序后,这些数据元素的相对次序保持不变,即为稳定,否则不稳定。
内排序与外排序是指按照排序过程中数据存储的存储设备的不同。内排序指被排序的数据元素全部存放在计算机的内存之中,并且在内存中调整数据元素的相对位置。外排序指数据元素主要存放在外存储器中,借助于内存储器逐步调整数据元素之间的相对位置。
以下各种算法代码实现,必须要一气呵成。熟能生巧,多写多练。所给方法可能并不全面,所以需要时常更新。
1、插入排序:每次将一个待排序的数据元素,按其关键字大小,插入到前面已经排好序的一组数据元素中的适当位置,直到所有的数据元素全部插入为止。
顺序存储实现:
//-----------------------------------------------------
//SimpleInsertSort
//-----------------------------------------------------
void simpleInsertSort(int a[], int size) {
int k;
int tmp;
for (int j = 1; j < size; ++j) {
tmp = a[j];
for (k = j - 1; tmp < a[k] && k >= 0; --k)
a[k + 1] = a[k];//从后住前移
a[k] = tmp;
}
}
链表存储实现:
Struct ListNode{
Int val;
ListNode *next;
ListNode(int x):val(x),next(nullptr){}
};
ListNode* insertSortList(ListNode* head){
ListNode* dummy=new ListNode(INT_MIN);
ListNode* cur=head;
ListNode* pre=dummy;
While(cur!=nullptr){
ListNode* next=cur->next;
pre=dummy;
while(pre->next!=nullptr&&pre->next->val<cur->val)
pre=pre->next;
cur->next=pre->next;
pre->next=cur;
cur=next;
}
ListNode* pHead=dummy->next;
Delete dummy;
Return pHead;
}
2、选择排序:从n个元素中选出关键字最小的元素,再从剩下的n-1个元素中选出n-1个元素中关键字最小的元素,依此类推,直至序列中最后只剩下一个元素为止。
顺序存储实现:
//-----------------------------------------------------
//SimpleSelectSort
//-----------------------------------------------------
void simpleSelectSort(int a[], int size) {
int i, j, maxk;
for (i = 0; i < size-1 ; ++i) {//因为选完倒数每二个数后,倒数第一个数一定是最大的
maxk = i;
for (j = i + 1; j < size ; ++j)
if (a[j] < a[maxk])
maxk = j;
swap(a[maxk], a[i]);
}
}
冒泡排序:
//-----------------------------------------------------
//bubbleSort
//-----------------------------------------------------
void bubbleSort(int a[], int size) {
bool flag = 0;
for (int i = 0; i < size - 1; ++i) {//一共是size-1次起泡
for (int j = 0; j < size - 1 - i; ++j) {
if (a[j] > a[j + 1]) {
swap(a[j], a[j + 1]);
flag = 1;
}
}
if (!flag)
break;
}
}
3、堆排序(此处实现的是最小堆排序)
//-----------------------------------------------------
//HeapSort
//-----------------------------------------------------
void heapFixup(int a[], int i) {//向上过滤
int tmp = a[i];
int f = i / 2 - 1;
while (f >= 0) {
if (tmp > a[f])
break;
a[i] = a[f];
i = f;
f = i / 2 - 1;
}
a[i] = tmp;
}
void heapInsert(int a[], int n,int val) {
a[n] = val;
heapFixup(a, n);
}
void heapFixdown(int a[], int i, int n) {//向下过滤
int tmp = a[i];
int s = 2 * i + 1;
while (s <= n) {
if (s + 1 <= n&&a[s] > a[s + 1])
++s;
if (tmp < a[s])
break;
a[i] = a[s];
i = s;
s = 2 * i + 1;
}
a[i] = tmp;
}
void heapDelete(int a[], int n) {
swap(a[0], a[n]);
heapFixdown(a, 0, n-1);
}
//堆排序的关键是实现向下过滤函数
void heapSort(int a[], int n) {
for (int i = n / 2 - 1; i >= 0; --i)
heapFixdown(a, i, n);
}
4、快排
//-----------------------------------------------------
//quickSort
//-----------------------------------------------------
int partition(int a[], int start, int end) {
int tmp = a[start];
int low = start, high = end;
do {
while (a[high] >= tmp)
--high;
if (low < high&&a[high]<tmp) {
a[low] = a[high];
++low;
}
while (a[low] <= tmp)
++low;
if (low<high&&a[low]>tmp) {
a[high] = a[low];
--high;
}
} while (low != high);
return low;
}
void quickSort(int a[], int start, int end) {
if (start == end)
return;
int mid = partition(a, start, end);
quickSort(a, start, mid - 1);
quickSort(a, mid + 1, end);
}
5、归并排序
//-----------------------------------------------------
//mergeSort
//-----------------------------------------------------
void merge(int a[], int start, int mid, int end) {
int i = start, j = mid + 1,k=0;
int *tmp = new int[end - start + 1];
while (i <= mid&&j <= end) {
if (a[i] < a[j]) {
tmp[k++] = a[i++];
}
else
tmp[k++] = a[j++];
}
while (i <= mid) tmp[k++] = a[i++];
while (j <= end) tmp[k++] = a[j++];
for (k = 0, i = start; i <= end; ++k, ++i)
a[i] = tmp[k];
delete[] tmp;
}
void mergeSort(int a[], int start, int end) {
if (start == end)
return;
int mid = (start + end) / 2;
mergeSort(a, start, mid);
mergeSort(a, mid + 1, end);
merge(a, start, mid, end);
}
6、二叉查找树(查找、插入、删除)
#include<iostream>
using namespace std;
struct TreeNode {
int val;
TreeNode* left, *right;
TreeNode(int x) :val(x), left(nullptr), right(nullptr) {}
};
/*
二叉查找树的查找实现
*/
bool BST_find(TreeNode* root, int& val) {
if (!root)
return false;
if (root->val > val)
BST_find(root->left, val);
else if (root->val < val)
BST_find(root->right, val);
else
return true;
}
/*
二叉查找树的插入实现
*/
void BST_insert(TreeNode* root, int &val) {
if (!root) {
root = new TreeNode(val);
return;
}
if (root->val > val)
BST_insert(root->left, val);
else if (root->val < val)
BST_insert(root->right, val);
else {
//cout << "This value has been existed in the tree" << endl;
return;
}
}
/*
二叉查找树的删除实现
*/
void BST_remove(TreeNode* root, int &val) {
if (!root) {
//cout << "There is no this value in the tree" << endl;
return;
}
if (root->val > val)
BST_remove(root->left, val);
else if (root->val < val)
BST_remove(root->right, val);
else {
if (root->right&&root->left) {//处理有两个儿子的节点
TreeNode* tmp=root->left;//在左子树中找最大值节点
while (!tmp->right)
tmp = tmp->right;
root->val = tmp->val;
BST_remove(tmp, tmp->val);
}
else {//处理一个儿子或没有儿子的节点
TreeNode* tmp = root;
root = root->left ? root->left : root->right;
delete tmp;
}
}
}