The next few blogs are about sorting: insertion sorting, exchange sorting, selection sorting;
Insertion class sorting includes direct insertion sort, bianry insertion sort, and Shell sort.
The sorting of exchange classes mainly includes bubble sort and quick sort.
Selection sort includes simple selection sort and heap sort.
Besides, there are merge sort, cardinal sort, etc.
This blog is about quick sort.
The data structure of sorting is introduced directly.
All sorting is stored in a linear table; all sorting algorithms cannot avoid swapping; swapping requires temporary variables; therefore, elements numbered 0 in a linear table are not stored in any valid elements; they are only used as temporary variables or records; for some algorithms, I will give local variables. The algorithm for making temporary variables; if you don't know much about linear tables; see the previous blog about linear tables;
Header file (sort.h);
# ifndef _SORT_ typedef int KeyType; typedef struct { KeyType key; }DataType; # endif
Header file (SeqList.h);
typedef struct { DataType data[MAXSIZE]; int length; }SeqList, * PSeqList; //Basic preparation for sorting linear tables; PSeqList Init_SeqList(void); bool Full_SeqList(PSeqList p); int Push_SeqList(PSeqList p, KeyType keyValue); void Traversal_SeqList(PSeqList p); ostream & operator<<(ostream & os, DataType dataValue); //Sorting method based on linear table; default from small to large; void StraightInsertSort(PSeqList p); void BinaryInsertSort(PSeqList p); void ShellInsert(PSeqList p, int gap); void ShellSort(PSeqList p, int * gaps, int len); void BubbleSort(PSeqList p); void SelectSort(PSeqList p); void HeapAdjust(PSeqList p, int n, int m); void HeapSort(PSeqList p); int BinaryOrder(PSeqList p, int low, int high); void QuickSort(PSeqList p, int low, int high);
Implementation file (SeqList.cpp);
# include "SeqList.h" PSeqList Init_SeqList(void) { PSeqList p = (PSeqList)malloc(sizeof(SeqList)); if (NULL != p) { p->length = 0; return p; } else { cout << "Memory allocate is error! " << endl; system("pause"); exit(0); } } bool Full_SeqList(PSeqList p) { if (p->length >= MAXSIZE) { return true; } else { return false; } } int Push_SeqList(PSeqList p, KeyType keyValue) { if (Full_SeqList(p)) { cout << "SeqList is full! " << endl; return -1; } p->data[p->length].key = keyValue; p->length++; return 0; } void Traversal_SeqList(PSeqList p) { for (int i = 0; i < p->length; i++) { cout << p->data[i] << " "; } cout << endl; return; } ostream & operator<<(ostream & os, DataType dataValue) { cout << dataValue.key; return os; } //Sorting method based on linear table; default from small to large; //Direct insertion sort; void StraightInsertSort(PSeqList p) { int i = 0; int j = 0; for (i = 2; i < p->length; i++) { //Copy to outpost; p->data[0] = p->data[i]; j = i - 1; while (p->data[0].key < p->data[j].key)//Must be greater than; otherwise it is not a stable ordering; { //Moving elements; p->data[j + 1] = p->data[j]; j--; } //Elements eventually move into the right place; p->data[j + 1] = p->data[0]; } return; } //Half insertion sort; void BinaryInsertSort(PSeqList p) { int i = 0; int j = 0; int low = 0; int mid = 0; int high = 0; for (i = 2; i < p->length; i++) { //Copy to outpost; p->data[0] = p->data[i]; //Find the insertion location; low = 1; high = i - 1; while (low <= high) { mid = (low + high) / 2; if (p->data[0].key >= p->data[mid].key)//Either greater than or equal to or less than; that is, the opposite; or it is not a stable ordering; { low = mid + 1; } else { high = mid - 1; } } //The moving element frees up the insertion position, where high + 1 is the final insertion position. for (j = i - 1; j >= high + 1; j--) { p->data[j + 1] = p->data[j]; } //Elements eventually move into the right place; p->data[j + 1] = p->data[0]; } return; } //Shell insertion; void ShellInsert(PSeqList p, int gap) { int i = 0; int j = 0; for (i = gap + i; i < p->length; i++) { if (p->data[i].key < p->data[i - gap].key) { p->data[0] = p->data[i]; for (j = i - gap; (j > 0) && (p->data[0].key < p->data[j].key); j = j - gap) { p->data[j + gap] = p->data[j]; } p->data[j + gap] = p->data[0]; } } return; } //Shell sorting; void ShellSort(PSeqList p, int * gaps, int len) { int i = 0; for (i = 0; i < len; i++) { ShellInsert(p, gaps[i]); } return; } //Bubble sort; void BubbleSort(PSeqList p) { int i = 0; int j = 0; for (i = 1; i < p->length - 1; i++) { for (j = 1; j < p->length - i; j++) { if (p->data[j].key > p->data[j + 1].key) { p->data[0] = p->data[j]; p->data[j] = p->data[j + 1]; p->data[j + 1] = p->data[0]; } } } return; } //Selection sort; void SelectSort(PSeqList p) { int i = 0; int j = 0; int t = 0; for (i = 1; i < p->length - 1; i++) { for (j = i + 1, t = i; j < p->length; j++) { if (p->data[t].key > p->data[j].key) { t = j; } } if (t != i) { p->data[0] = p->data[i]; p->data[i] = p->data[t]; p->data[t] = p->data[0]; } } } void HeapAdjust(PSeqList p, int n, int m) { int i = n; int j = 0; DataType rec = p->data[i]; for (j = 2 * i; j <= m; j = 2 * j) { if ((j < m) && (p->data[j].key < p->data[j + 1].key)) { j = j + 1; } if (rec.key > p->data[j].key) { break; } else { p->data[i] = p->data[j]; i = j; } } p->data[i] = rec; return; } void HeapSort(PSeqList p) { int i = 0; for (i = (p->length - 1) / 2; i > 0; i--) { HeapAdjust(p, i, p->length - 1); } for (i = p->length - 1; i > 1; i--) { p->data[0] = p->data[i]; p->data[i] = p->data[1]; p->data[1] = p->data[0]; HeapAdjust(p, 1, i - 1); } return; } int BinaryOrder(PSeqList p, int low, int high) { KeyType keyValue; p->data[0] = p->data[low]; keyValue = p->data[low].key; while (low < high) { while ((low < high) && (p->data[high].key >= keyValue)) { high--; } p->data[low] = p->data[high]; while ((low < high) && (p->data[low].key <= keyValue)) { low++; } p->data[high] = p->data[low]; } p->data[low] = p->data[0]; return low; } void QuickSort(PSeqList p, int low, int high) { int mid = 0; if (low < high) { mid = BinaryOrder(p, low, high); QuickSort(p, low, mid - 1); QuickSort(p, mid + 1, high); } return; }
Main.cpp;
# include "SeqList.h" int main(int argc, char ** argv) { int val = 0; PSeqList p = Init_SeqList(); for (int i = 0; i <= 10; i++) { Push_SeqList(p, 11 - i); } cout << "---------------Sort befor---------------" << endl; Traversal_SeqList(p); cout << endl << "---------------Sort after---------------" << endl; //StraightInsertSort(p); //BinaryInsertSort(p); //BubbleSort(p); QuickSort(p, 1, 10); //SelectSort(p); /HeapSort(p); //MergeSort(p->data, p->data, 1, p->length - 1); //StraightInsertAllSort(p); //BinaryInsertAllSort(p); Traversal_SeqList(p); system("pause"); return 0; }
The above algorithm only ranks the elements of {1... N}; the following algorithm ranks the elements of {0... N};
Analysis: No element 0 was sorted before because element 0 was used as a temporary variable. Now you can customize a temporary variable to replace it.
int BinaryQuickAllSort(PSeqList p, int low, int high) { DataType tem = p->data[low]; KeyType midKeyValue = p->data[low].key; while (low < high) { while (low < high && p->data[high].key >= midKeyValue) { high--; } p->data[low] = p->data[high]; while (low < high && p->data[low].key <= midKeyValue) { low++; } p->data[high] = p->data[low]; } p->data[low] = tem; return low; } void QuickAllSort(PSeqList p, int low, int high) { int mid = 0; if (low < high) { mid = BinaryQuickAllSort(p, low, high); QuickAllSort(p, low, mid - 1); QuickAllSort(p, mid + 1, high); } return; }