各种排序
#include <stdlib.h>
#include <iostream>
#include<time.h>
#include<math.h>
using namespace std;
//*************************数据元素
class RedType
{
public:
int key; //关键字项
};
//************************顺序表
class SqList
{
RedType r[20 + 1]; //顺序表最大长度+1,第0单元闲置或做哨兵
int length; //顺序表长度
public:
void CreatList(); //随机生成16个2位正整数(10-99),创建顺序表
void ShowResult(); //输出最终结果
void InsertSort(); //1,直接插入排序,从小到大
void SelectSort(); //2,选择排序
void BubbleSort(); //3,冒泡排序
void DoubleBubbleSort(); //4,双向冒泡排序
void QuickSort(); //5,快速排序
int Partition(int low, int high);//5,完成一趟快速排序,并返回 Low 位置
void QSort(int low, int high); //5,对子序列 [low.....high] 做快速排序
void MergeSort(); //6,二路归并排序
void Merge(RedType R[], RedType T[], int low, int mid, int high); //6,将两个有序表排序后,归并到一个有序表中
void MSort(RedType R[], RedType T[], int low, int high); //6,划分有序表,通过 Merge 排序后合并;
void ShellSort(); //7,希尔排序
void ShellInsert(int dk); //7,增量是 dk 的希尔插入排序
void HeapSort(); //8,堆排序
void creatHeap(); //8,建初堆
void HeapAjust(int s, int m); //8,筛选法调整堆
};
int main()
{
SqList L;
cout << "注:中间过程的“(”和“)”是括起已经排好序的部分" << endl;
cout << "直接插入排序: " << endl;
L.InsertSort();
cout << "选择排序: " << endl;
L.SelectSort();
cout << "冒泡排序: " << endl;
L.BubbleSort();
cout << "双向冒泡排序: " << endl;
L.DoubleBubbleSort();
cout << "快速排序: " << endl;
L.QuickSort();
cout << "二路归并排序: " << endl;
L.MergeSort();
cout << "希尔排序: " << endl;
L.ShellSort();
cout << "堆排序: " << endl;
L.HeapSort();
}
void SqList::CreatList()
{
time_t t;
srand((unsigned)time(&t));
this->length = 16;
cout << "创建随机16个2位正整数(10-99)顺序表: " << endl;
for (int i = 1; i <= 16; i++)
{
this->r[i].key = rand()%89 + 10;
cout << this->r[i].key << ends;
}
cout << endl << endl;
}
void SqList::ShowResult()
{
cout << "最终结果:";
for (int i = 1; i <= 16; i++)
{
cout << this->r[i].key << ends;
}
cout << endl <<endl;
}
void SqList::InsertSort()
{
this->CreatList();
int movetimes=0; //记录移动次数
int keyCompare=0; //记录关键字比较次数
int sortimes = 0; //记录排序次数
for (int i = 2; i <= this->length; ++i)
{
keyCompare++;
if (this->r[i].key < this->r[i - 1].key) //上一个值比当前值大
{
this->r[0] = this->r[i];
this->r[i] = this->r[i - 1]; //上一个值向后移
movetimes++;
int j = i - 2;
keyCompare++; //for循环里至少执行一次
for (; this->r[0].key < this->r[j].key && j >= 0; --j) //从后向前,直到发现比当前值小的值,在已经排好序的序列里寻找位置
{
this->r[j + 1] = this->r[j]; //比当前值大则后移
movetimes++;
keyCompare++;
}
this->r[j + 1] = this->r[0];
sortimes++; //排序次数+1
cout << "第" << sortimes << "次排序:";
for (int j = 1; j <= 16; j++)
{
if(j==i) cout << this->r[j].key <<" )" <<ends;
else cout << this->r[j].key << ends;
}
cout << endl;
}
}
cout << "统计关键字的比较次数、记录的移动次数分别为:" << keyCompare << ends << movetimes << endl;
this->ShowResult();
}
void SqList::SelectSort()
{
this->CreatList();
int movetimes = 0; //记录移动次数
int keyCompare = 0; //记录关键字比较次数
int sortimes = 0; //记录排序次数
for (int i = 1; i < this->length; ++i)
{
int k = i;
for (int j = i + 1; j <= this->length; ++j) //从未排序中寻找最小值
{
keyCompare++;
if (this->r[j].key < this->r[k].key) k = j;
}
if (k != i) //不等则交换位置
{
RedType t = this->r[i];
this->r[i] = this->r[k];
this->r[k] = t;
movetimes++;
}
sortimes++; //排序次数+1
cout << "第" << sortimes << "次排序:";
for (int j = 1; j <= 16; j++)
{
if (j == i) cout << this->r[j].key << " )" << ends;
else cout << this->r[j].key << ends;
}
cout << endl;
}
cout << "统计关键字的比较次数、记录的移动次数分别为:" << keyCompare << ends << movetimes << endl;
this->ShowResult();
}
void SqList::BubbleSort()
{
this->CreatList();
int movetimes = 0; //记录移动次数
int keyCompare = 0; //记录关键字比较次数
int sortimes = 0; //记录排序次数
int m = this->length;
int flag = 1; //用来标记某次排序是否交换过
while ((m > 0) && (flag = 1))
{
flag = 0;
for (int j = 1; j < m; ++j)
{
keyCompare++;
if (this->r[j].key > this->r[j + 1].key)
{
flag = 1;
RedType t = this->r[j];
this->r[j] = this->r[j + 1];
this->r[j + 1] = t;
movetimes++;
}
}
--m;
if (flag == 1)
{
sortimes++; //排序次数+1
cout << "第" << sortimes << "次排序:";
for (int j = 1; j <= 16; j++)
{
if (j == m) cout << this->r[j].key << " (" << ends;
else cout << this->r[j].key << ends;
}
cout << endl;
}
}
cout << "统计关键字的比较次数、记录的移动次数分别为:" << keyCompare << ends << movetimes << endl;
this->ShowResult();
}
void SqList::DoubleBubbleSort()
{
this->CreatList();
int movetimes = 0; //记录移动次数
int keyCompare = 0; //记录关键字比较次数
int sortimes = 0; //记录排序次数
int m = this->length; //重的下沉
int n = 0; //轻的上升
int flag = 1; //用来标记某次排序是否交换过
while ((m!=n) && (flag = 1))
{
flag = 0;
for (int j = 1; j < m; ++j)
{
keyCompare++;
if (this->r[j].key > this->r[j + 1].key)
{
flag = 1;
RedType t = this->r[j];
this->r[j] = this->r[j+1];
this->r[j+1] = t;
movetimes++;
}
}
for (int j = m-1; j>n; --j)
{
keyCompare++;
if (this->r[j].key > this->r[j + 1].key)
{
flag = 1;
RedType t = this->r[j];
this->r[j] = this->r[j + 1];
this->r[j + 1] = t;
movetimes++;
}
}
--m;
++n;
if (flag == 1)
{
sortimes++; //排序次数+1
cout << "第" << sortimes << "次排序:";
for (int j = 1; j <= 16; j++)
{
if (j == n) cout << this->r[j].key << " )" << ends;
else if (j == m) cout << this->r[j].key << " (" << ends;
else cout << this->r[j].key << ends;
}
cout << endl;
}
}
cout << "统计关键字的比较次数、记录的移动次数分别为:" << keyCompare << ends << movetimes << endl;
this->ShowResult();
}
int Qmovetimes = 0; //记录移动次数
int QkeyCompare = 0; //记录关键字比较次数
int Qsortimes = 0; //记录排序次数
int Qflag = 1;
void SqList::QuickSort()
{
this->CreatList();
QSort(1, this->length);
cout << "统计关键字的比较次数、记录的移动次数分别为:" << QkeyCompare << ends << Qmovetimes << endl;
this->ShowResult();
}
int SqList::Partition(int low, int high)
{
Qflag = 0;
this->r[0] = this->r[low];
int pivotkey = this->r[low].key;
while (low < high)
{
QkeyCompare++;
while (low < high && this->r[high].key >= pivotkey)
{
QkeyCompare++;
--high;
}
if (low != high)
{
this->r[low] = this->r[high]; //low在前,high在后,high向前走,遇到high比low小,将low的值换为high的值
Qmovetimes++;
Qflag = 1;
}
QkeyCompare++;
while (low < high && this->r[low].key <= pivotkey)
{
QkeyCompare++;
++low;
}
if (low != high)
{
this->r[high] = this->r[low]; //low在前,high在后,low向后走,遇到high比low小,将high的值换为low的值
Qmovetimes++;
Qflag = 1;
}
}
this->r[low] = this->r[0];
if (Qflag == 1)
{
Qsortimes++; //排序次数+1
cout << "第" << Qsortimes << "次排序:";
for (int j = 1; j <= 16; j++)
{
cout << this->r[j].key << ends;
}
cout << endl;
}
return low;
}
void SqList::QSort(int low, int high)
{
if (low < high)
{
int pivotloc = Partition(low, high);
QSort(low, pivotloc-1);
QSort(pivotloc + 1, high);
}
}
int Mmovetimes = 0; //记录移动次数
int MkeyCompare = 0; //记录关键字比较次数
int Msortimes = 0; //记录排序次数
int Mflag = 1;
void SqList::MergeSort()
{
this->CreatList();
MSort(this->r, this->r, 1, this->length);
cout << "统计关键字的比较次数、记录的移动次数分别为:" << MkeyCompare << ends << Mmovetimes << endl;
this->ShowResult();
}
void SqList::Merge(RedType R[], RedType T[], int low, int mid, int high)
{
int i = low; //指向 R[low....mid] 的第一个元素
int j = mid + 1; //指向 R[mid+1....high] 的第一个元素
int k = low; //指向元素进入 T[low...high]的位置
//cout << "i j k : " << i << ends << j << ends << k << endl;
while (i <= mid && j <= high) //直到 R[low....mid]或 R[mid+1....high]的全部元素进 T
{
MkeyCompare++;
Mmovetimes++;
if (R[i].key <= R[j].key) T[k++] = R[i++]; //值小的在R[low....mid],进 T, T的位置指向下一个,R[low....mid] 也指向下一个元素
else T[k++] = R[j++]; //值小的在R[mid+1....high],进 T, T的位置指向下一个,R[mid+1....high] 也指向下一个元素
}
while (i <= mid)
{
T[k++] = R[i++]; // R[low....mid]剩余元素进 T
Mmovetimes++;
}
while (j <= high)
{
T[k++] = R[j++];// R[mid+1....high]剩余元素进 T
Mmovetimes++;
}
if (low == 1)
{
Msortimes++; //排序次数+1
cout << "第" << Msortimes << "趟归并:";
for (int j = low; j <= high; j++)
{
cout << T[j].key << ends;
}
cout << endl;
}
}
void SqList::MSort(RedType R[], RedType T[], int low, int high)
{
if (low == high) T[low] = R[low]; //序列内只有单个值时返回
else
{
int mid = (low + high) / 2; //划分点 mid
RedType *S=new RedType[21];
MSort(R, S, low, mid); //对子序列 R[low...mid] 递归并排序,结果放入 S[low...mid]中
MSort(R, S, mid+1, high); //对子序列 R[mid+1...high] 递归并排序,结果放入 S[mid+1...high]中
Merge(S, T, low, mid, high); //将 S[low...mid] 和 S[mid+1...high]合并到 T[low...high]
}
}
int Smovetimes = 0; //记录移动次数
int SkeyCompare = 0; //记录关键字比较次数
int Ssortimes = 0; //记录排序次数
void SqList::ShellSort()
{
//"增量为 7 5 3 1"
this->CreatList();
for (int k = 7; k >0;)
{
ShellInsert(k);
k -= 2;
}
this->ShowResult();
}
void SqList::ShellInsert(int dk)
{
for (int i = dk + 1; i <= this->length; i++)
{
SkeyCompare++;
if (this->r[i].key < this->r[i - dk].key)
{
this->r[0] = this->r[i];
int j = i - dk;
SkeyCompare++;
for ( j; j > 0 && this->r[0].key < this->r[j].key; j -= dk)
{
this->r[j + dk] = this->r[j];
Smovetimes++;
SkeyCompare++;
}
this->r[j + dk] = this->r[0];
Smovetimes++;
}
}
Ssortimes++; //排序次数+1
cout << "第" << Ssortimes << "趟增量为"<<dk<<"的排序:";
for (int j = 1; j <= 16; j++)
{
cout << this->r[j].key << ends;
}
cout << endl;
}
int Hmovetimes = 0; //记录移动次数
int HkeyCompare = 0; //记录关键字比较次数
int Hsortimes = 0; //记录排序次数
void SqList::HeapSort()
{
this->CreatList();
creatHeap(); //建大根堆
int i = this->length;
for (; i > 1; i--)
{
RedType x = this->r[1]; //栈顶与未排序序列的最后一个,即最小值,对换
this->r[1] = this->r[i];
this->r[i] = x;
Hmovetimes++;
HeapAjust(1, i - 1); //重新调整大根堆
}
cout << "统计关键字的比较次数、记录的移动次数分别为:" << HkeyCompare << ends << Hmovetimes << endl;
this->ShowResult();
}
void SqList::creatHeap()
{
int n = this->length;
for (int i = n / 2; i > 0; i--)
HeapAjust(i, n); //初始时,未进行排列,故未排列序列一直等于初始序列长
}
void SqList::HeapAjust(int s, int m)
{
RedType rc = this->r[s];
for (int j = 2 * s; j <= m; j *= 2) //逐层遍历
{
HkeyCompare++;
if (j < m&&this->r[j].key < this->r[j + 1].key) ++j; //指向另一个儿子
HkeyCompare++;
if (rc.key >= this->r[j].key) break; //rc的值比它的儿子大,无需调换
this->r[s] = this->r[j]; //儿子比它大,换位
s = j;
Hmovetimes++;
}
this->r[s] = rc;
Hmovetimes++;
if (m != this->length)
{
Hsortimes++; //排序次数+1
cout << "第" << Hsortimes << "次交换操作以及调整栈堆之后:";
for (int j = 1; j <= 16; j++)
{
cout << this->r[j].key << ends;
}
cout << endl;
}
}
顺序查找和折半查找
#include <stdlib.h>
#include <iostream>
#include<time.h>
#include<math.h>
using namespace std;
class SSTable
{
char *keys = new char[17]; //使用数组结构
int length;
public:
int compare;
public:
void creatsstable(); //用随机函数生成16个不重复的字母(’a’~’z’)
int Search_seq(char k); //顺序查找,若成功则返回位置(序号)
void InsertSort(); //插入排序
int Search_bin(); //折半查找
};
int main()
{
SSTable ST;
ST.creatsstable();
cout << "顺序查找:" << endl ;
char k = 1;
while (k!='0')
{
cout << "请输入要查找的字母( 范围为 a-z, 按0退出):";
cin >> k;
if (k >= 'a'&&k <= 'z')
{
int position = ST.Search_seq(k);
if (position == 0)
{
cout << "查找" << ST.compare << "次,"<<"查无此值! ";
}
else cout << "查找" << ST.compare << "次," << "该值在第" << position << " 个位置(序号)" << endl ;
}
else if (k == '0') break;
else cout << "输入错误 ! ";
}
cout << endl<< "折半查找:" << endl ;
ST.Search_bin();
}
void SSTable::creatsstable()
{
time_t t;
srand((unsigned)time(&t));
this->length = 16;
this->compare = 0;
cout << "创建随机16个不重复的字母('a'- 'z')顺序表: " << ends;
for (int i = 1; i <= 16; i++)
{
char k;
int flag = 0;
while (flag == 0)
{
flag = 1;
k = 'a' + rand() % ('z' - 'a' + 1);
for (int j = 1; j < i; j++)
{
if (k == this->keys[j]) flag = 0;
}
}
this->keys[i] = k;
cout << this->keys[i] << ends;
}
cout << endl << endl;
}
int SSTable::Search_seq(char k)
{
this->compare = 1; //至少比较一次
int i = this->length;
for (; i >= 1; --i)
{
this->compare++;
if (this->keys[i] == k) return i;
}
return 0;
}
void SSTable::InsertSort()
{
for (int i = 2; i <= this->length; ++i)
{
if (this->keys[i] < this->keys[i-1]) //上一个值比当前值大
{
this->keys[0] = this->keys[i];
this->keys[i] = this->keys[i - 1]; //上一个值向后移
int j = i - 2;
for (; this->keys[0] < this->keys[j] && j >= 0; --j) //从后向前,直到发现比当前值小的值,在已经排好序的序列里寻找位置
{
this->keys[j + 1] = this->keys[j]; //比当前值大则后移
}
this->keys[j + 1] = this->keys[0];
}
}
cout << "排序后的数组:";
for (int j = 1; j <= 16; j++)
{
cout << this->keys[j] << ends;
}
cout << endl;
}
int SSTable::Search_bin()
{
char k = 1;
this->InsertSort();
while (k != '0')
{
cout << "请输入要查找的字母( 范围为 a-z, 按0退出):";
cin >> k;
if (k >= 'a'&&k <= 'z')
{
this->compare = 0; //至少比较一次
int position = 0;
//*******************************************************开始查找
int low = 1, high = this->length;
while ((low <= high)&&position==0)
{
int mid = (low + high) / 2;
this->compare++;
if (k == this->keys[mid]) position = mid;
else if (k < this->keys[mid]) high = mid - 1;
else low = mid + 1;
}
cout << "比较" << this->compare << "次,";
//*****************************************************查找结束
if (position == 0)
{
cout << "查无此值! ";
}
else cout << "该值在第" << position << " 个位置(序号)" << endl;
}
else if (k == '0') break;
else cout << "输入错误 ! ";
}
return 0;
}
二叉排序树
// (3)二叉查找树:手工输入10个字母,生成一棵二叉查找树,
// 用递归算法打印树结构或分别输出先序和中序遍历序列以确认其结构。
// 键盘输入待查找的字母,计算比较次数。分别用查找成功、不成功进行测试。
#include "pch.h"
#include <iostream>
using namespace std;
#define OK 1
#define ERROR 0
typedef char Status;
typedef struct
{
char key;
}ElemType;
typedef struct BSTNode
{
ElemType data;
struct BSTNode *lchild, *rchild;
}BSTNode, *BSTree;
//********************************************插入新结点
void InsertBBS(BSTree &T, ElemType e)
{
if ( T==NULL )
{
BSTNode *s=new BSTNode;
s->data = e;
s->lchild = s->rchild = NULL;
T = s;
cout << T->data.key << "插入成功" << endl;
}
else if (e.key < T->data.key) {InsertBBS(T->lchild, e);}
else if (e.key > T->data.key) {InsertBBS(T->rchild, e);}
else if (e.key == T->data.key)
{
cout << T->data.key << "相等" << endl;
BSTNode *s = new BSTNode;
BSTNode *p = new BSTNode;
p = T->lchild;
s->data = e;
s->lchild = p;
s->rchild = NULL;
T->lchild = s;
}
}
//******************************************手动输入10个字母生成二叉树
void creatBSTree(BSTree &T)
{
for (int i = 0; i < 10; i++) //十个字母
{
cout << "请输入第" << i+1 << "个字母( 范围为 a-Z ):";
char k = 0;
while (k == 0) //输入是字母时跳出循环
{
cin >> k;
ElemType e;
e.key = k;
if (k >= 'A'&& k <= 'z') { InsertBBS(T, e); }
else { k = 0; cout << "输入错误 ! 请重新输入: "; }
}
}
cout << "二叉排序树创建成功" << endl;
}
//*********************************************中序遍历输出结构
void InOrder(BSTree T)
{
if (T != NULL)
{
InOrder(T->lchild);
cout << T->data.key << ends;
InOrder(T->rchild);
}
}
//*********************************************先序遍历输出结构
void PreOrder(BSTree T)
{
if (T != NULL)
{
cout << T->data.key << ends;
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
//************************************************二叉排序树的查找
int compare ;
BSTree SearchBBT(BSTree T, char k)
{
compare++;
if (T == NULL || k == T->data.key) return T; //成功则返回T,失败返回空指针
else if (k < T->data.key) { return SearchBBT(T->lchild, k); } //比T小,在左儿子找
else return SearchBBT(T->rchild, k); //比T小,在右儿子找}
}
int main()
{
BSTree T = NULL;
creatBSTree(T);
cout << "先序遍历:";
PreOrder(T);
cout << endl;
cout << "中序遍历:";
InOrder(T);
cout << endl;
char k = 1;
while (k != '0')
{
cout << "请输入要查找的字母(按0退出):";
cin >> k;
if (k >= 'A'&& k <= 'z')
{
BSTNode *p = new BSTNode;
compare = 0;
p = SearchBBT(T, k);
if (p) cout << "比较" << compare << "次," << p->data.key << "查找成功!" << endl << endl;
else cout << "比较" << compare << "次," << "查无此值! ";
}
else if (k == '0') break;
else cout << "输入错误 ! ";
}
}