idk why these stuffs get stashed for so long and I didn't ever commit them

This commit is contained in:
2025-11-06 09:43:54 +08:00
parent 5dbdfef1a1
commit e01c041259
232 changed files with 22806 additions and 1256 deletions

580
OrigFiles/8-排序/Sort.cpp Normal file
View File

@@ -0,0 +1,580 @@
#include<iostream>
//#include"assert.h"
//#include"sort.h"
using namespace std;
// 测试数据集,0单元未用
int IA[9]={0,58,40,65,97,87,8,17,58}; // 直接插入、折半插入
int SA[11]={0,58,40,65,97,87,8,17,58,46,60}; // 希尔
int BA[9]={0,58,40,65,97,87,8,17,58}; // 冒泡
int QA[9]={0,58,35,65,97,87,8,17,58}; // 快速
int SSA[9]={0,58,35,25,97,87,8,58,17}; // 简单选择排序
int HA[9]={0,38,25,16,36,18,32,28,50}; // 堆排序
int EA1[8]={0,58,40,25,87,8,58,17}; // 归并
int EA2[9]={0,8,4,5,2,6,3,7,9}; // 递归归并
int RA[9]={0,769,763,63,249,243,545,281,89}; // 基数排序
void CopyData(int a[],int n, int R[]) // 数据后移一个单元从1单元开始
{
for(int i=1;i<=n;i++)
R[i]=a[i];
}
void DispData(int R[], int n) // 数据显示
{
int i;
for(i=1;i<=n;i++)
cout<<R[i]<<'\t';
cout<<endl;
}
// 算法8.1 直接插入排序
void InsertSort(int R[], int n)
{
int i, j;
for(i=2; i<=n; i++) // 从第2个元素开始
{
if(R[i-1]>R[i]) // 1.如果R[i-1]>R[i]
{
R[0]=R[i]; // 1.1 R[i]复制为监视哨
R[i]=R[i-1]; // 1.2 R[i]后移
for(j=i-2;R[j]>R[0];--j) // 1.3 j从i-2开始如果R[j]>R[0] R[j]后移j--
R[j+1]=R[j]; // 1.4 插入R[i]i++
R[j+1]=R[0];
}
cout<<""<<i-1<<"\t"; // 显示每趟排序结果
DispData(R,n);
} // 2.否则i++,进入下一趟
}
//算法8.2 折半插入排序
void BInsertSort(int R[],int n)
{
int i,j,m;
int low,high;
for(i=2; i<=n; i++) // n个记录进行n-1趟
{
R[0]=R[i]; // 1.保存R[i]
low=1; // 2.用折半查找方法,找插入点
high=i-1; // 2.1 设置查找范围的下界和上界
while(low<=high) // 2.2 只要low<=high
{
m=(low+high)/2; // 2.2.1计算中间位置m
if(R[m]>R[i]) high=m-1; // 2.2.2 R[m]>R[0],调整查询上界
else low=m+1; // 否则,调整查找下界
} // 3.插入点high+1后元素移动
for(j=i-1;j>=high+1;--j) // 3.1 R[i-1]R[high+1]依次后移
R[j+1]=R[j]; // 3.2 R[i]复制到R[high+1]
R[high+1]=R[0];
cout<<""<<i-1<<"\t"; // 显示每趟排序结果
DispData(R,n);
}
}
//算法8.3 希尔排序
void ShellInsert(int R[],int n,int dk) // 增量为dk的一趟希尔排序
{
int i,j;
for(i=dk+1;i<=n;++i)
if(R[i]<R[i-dk]) // 通过下标间距控制一起插入排序的元素d组同时进行。
{
R[0]=R[i];
for(j=i-dk;j>0 && (R[0]<R[j]); j-=dk)
R[j+dk]=R[j];
R[j+dk]=R[0];
}
}
void ShellSort(int R[],int n,int d[],int t)
{
int k;
for(k=0;k<t;k++) // t个增量
{
ShellInsert(R,n,d[k]); // 进行t趟
cout<<""<<k+1<<"\t"; // 显示每趟排序结果
DispData(R,n);
}
}
//算法8.4 冒泡排序
void Bubble_Sort(int R[],int n)
{
int i,j,temp;
bool exchange;
for(i=1,exchange=true;i<n && exchange; i++) // 增量为dk的一趟希尔排序操作结束。
{ // 一趟排序工作如下:
exchange=false; // 1.设置交换标志初值为无交换
for(j=1;j<=n-i;j++) // 2.从表首开始两两比较
{
if (R[j]>R[j+1]) // 2.1相邻元素逆序,互换位置
{
temp=R[j],R[j]=R[j+1],R[j+1]=temp; // R[j]<-->R[j+1]
exchange=true; // 2.2 交换标志改为true
}
}
cout<<""<<i<<"\t"; // 显示每趟排序结果
DispData(R,n);
}
}
//算法8.5 一次划分
int Partition(int R[],int low,int high)
{
int pivot;
pivot=R[low]; // 1. 第1个记录为枢轴
while(low<high) // 2. 扫描完所有记录,退出循环
{
while(low<high && R[high]>=pivot) // 2.1 从高端做起,
--high; // 2.1.1 比枢轴大,位置不动
R[low]=R[high]; // 2.1.2 比枢轴小,记录移到低端
while(low <high && R[low]<=pivot) // 2.2 转到低端,
++low; // 2.2.1 比枢轴小,位置不动
R[high]=R[low]; // 2.2.2 比枢轴大,记录移到高端
cout<<endl; // 转至高端
}
R[low]=pivot; // 3. 扫描结束,枢轴记录定位
return low; // 4. 返回枢轴位置。
}
//算法8.6 快速排序递归算法
void QSort(int R[],int low,int high) // 对R[n]进行快速排序
{
int pivoitloc;
if(low<high) // 序列长度大于1//进行下列操作
{
pivoitloc=Partition(R,low,high); // 1. 一次划分
cout<<"枢轴元素:"<<R[pivoitloc]; // 轴出各趟枢轴元素
QSort(R,low,pivoitloc-1); // 2. 对低子序列递归排序
QSort(R,pivoitloc+1,high); // 3. 对高子序列递归排序
}
}
//算法8.7 简单选择排序
void SelectSort(int R[],int n)//对R[n]进行简单选择排序
{
int i,j,t,mink;
for(i=1;i<n;++i) // 共需n-1趟每一趟操作如下
{
mink=i; // 1.查找最小关键码记录号mink
for(j=i+1;j<=n;++j)
if(R[j]<R[mink])
mink=j;
if(mink!=i) // 2.如果最小记录不是第i个
{
t=R[i];R[i]=R[mink];R[mink]=t; // 3.R[i]←→R[mink]
}
cout<<""<<i<<"\t"; // 显示每趟排序结果
DispData(R,n);
}
}
//算法8.8 一次筛选
void HeapAdjust(int R[],int s,int n) //将R[s..n]调整为以R[s]为根的大根堆
{
int j;
R[0]=R[s]; // 1.复制R[s]让出R[s]空间
for(j=2*s;j<=n;j=2*s) // 2.一次筛选
{
if(j<n && R[j]<R[j+1]) // 2.1比较子树根的两个孩子,取较大者
j++;
if(R[0]>R[j]) // 2.2子树根大于较大者,无需记录移动
break;
R[s]=R[j]; // 2.3 否则R[j]为子树根
s=j; // 2.4 考量下一级子树,
}
R[s]=R[0]; // R[s]插入到合适位置
}
//算法8.9 建堆
void CreateHeap(int R[],int n) //把无序序列R[1..n]建成大根堆
{
int i;
for(i=n/2;i>0;--i) // 从首个非叶结点开始
{
HeapAdjust(R,i,n); // 反复调用HeapAdjust逐个调整。
}
cout<<"\t"; // 输出堆
DispData(R,n);
}
//算法8.10 堆排序
void HeapSort(int R[],int n)
{
int i,t;
CreateHeap(R,n); // 建堆
for(i=1;i<n;i++)
{
t=R[1];R[1]=R[n-i+1];R[n-i+1]=t; // 堆顶与堆尾元素互换位置
cout<<""<<i<<"\t"; // 显示每趟排序结果
DispData(R,n);
HeapAdjust(R,1,n-i); // 调整成堆
}
}
//算法8.11 两个有序列合并
void Merge(int R[],int s, int m, int t) // 两个有序序列R[s..m]、R[m+1..t]合并一个有序序列
{
int *R1; // 1. 初始化
int i,j,n,k;
n=t+1; //1.1辅助数组临存归并结果
R1=new int[n]; // 1.2 设3个工作指针i、j、k分别指向R[s]、R[m+1]、R1[]首元处
i=s;
j=m+1;
k=s;
while(i<=m && j<=t) // 2.两个序列合并2.1两个序列均不空
{
if(R[i]<=R[j])
R1[k++]=R[i++];
else
R1[k++]=R[j++];
}
while(i<=m) // 2.2若第1个子序列未处理完,R[m+1..t]为剩余记录
R1[k++]=R[i++];
while(j<=t) // 2.3若第2个子序列未处理完将其剩余部分复制到R1
R1[k++]=R[j++];
for(k=s,i=s;i<=t;k++,i++) // 3.将R1复制到R[s..t]中
R[i]=R1[k];
delete R1; // 释放R1。
}
//算法8.12 一趟归并
void MergePass(int R[],int n,int len)
{
int i=1; // 序列下标从1开始
while(i+2*len-1<=n) // 等长子序列合并
{
Merge(R,i,i+len-1,i+2*len-1);
i+=2*len;
}
if(i+len-1<n) // 不等长子序列
Merge(R,i,i+len-1,n);
}
//算法8.13 2-路归并算法
void MergeSort(int R[],int n)
{
int len;
for(len=1;len<=n;len=len*2) // 初始子序列长度为1
{
MergePass(R,n,len); // 子序列合并
cout<<""<<len/2+1<<"\t"; // 显示每趟排序结果
DispData(R,n);
}
}
//算法8.14 2-路归并递归算法
void MSort(int R[],int s,int t)
{
int m; //1.待排序记录只有1个递归结束
if(s<t)
{
m=(s+t)/2; //2. 序列对半分
MSort(R,s,m); //3. 递归归并前半个子序列
MSort(R,m+1,t); //4. 递归归并后半个子序列
Merge(R,s,m,t); //5. 左、右两个子序列归并
}
}
void MergeSort1(int R[], int n)
{
MSort(R,1,n); // 初次调用
}
struct RNode // 多关键字结点
{
int keys[3]; // 设关键字数为d=3
struct RNode *next;
};
void CreateDL(RNode *&L,int R[],int n) // 尾插法建无头结点单链表,存储待排序记录
{
int i;
RNode *p,*rr;
for(i=1;i<=n;i++)
{
p=new RNode;
//cout<<"R[i]"<<R[i]<<'\t';
p->keys[0]=R[i]/100; // 百位
p->keys[1]=R[i]%100/10; // 十位
p->keys[2]=R[i]%100%10; // 个位
p->next=NULL;
if (i==1) // 首元结点
{
L=p;
rr=L;
}
else // 非首元结点
{
rr->next=p;
rr=p;
}
cout<<endl;
}
}
void DispDL(RNode *L)
{
int d;
RNode *p;
p=L;
while(p!=NULL)
{
for(d=0;d<3;d++)
cout<<p->keys[d];
cout<<'\t';
p=p->next;
}
cout<<endl;
}
//算法8.15 基数排序
void RadixSort(RNode *&L,int r,int d) // r进制数、d位数的基排序
{
int i,j,k;
RNode *h[10],*t[10],*T; // 10进制数建立10个队列
for(i=d-1;i>=0;i--) // d个数位d个关键字d趟
{ // 每一趟
for(j=0;j<r;j++) // 1.队列初始化
h[j]=t[j]=NULL;
while(L!=NULL) // 2.扫描序列列表,进行分
{
k=L->keys[i]; // 2.1第i个子关键字为k则入第k个队列
if(h[k]==NULL) // 2.1.1首元结点,
{
h[k]=L;t[k]=L; // 队尾指向队头
}
else // 2.1.2非首元结点,
{
t[k]->next=L; t[k]=L; // 入队尾
}
L=L->next; // 2.2 取一下待排序记录
}
L=NULL; // 收集
for(j=0;j<r;j++) // 3.1 r个队列尾-首相连
{
if(h[j]!=NULL) // 3.1.2首元结点
{
if(L==NULL) // 队尾指向队头
{
L=h[j];T=t[j];
}
else // 3.1.3 非首元结点,
{
T->next=h[j];T=t[j]; // 首尾相接
}
}
}
T->next=NULL; // 尾结点next为空
cout<<""<<d-i<<""<<'\t';
DispDL(L);
}
}
void dispmenu()
{
cout<<"* 主 菜 单 *"<<endl;
cout<<"---------------"<<endl;
cout<<"* 插 入 排 序 * "<<endl
<<" 1 直接插入排序"<<endl
<<" 2 折半插入排序"<<endl
<<" 3 希尔排序"<<endl
<<endl;
cout<<"* 交 换 排 序 *"<<endl
<<" 4 起泡排序"<<endl
<<" 5 快速排序"<<endl
<<endl;
cout<<"* 选 择 排 序 *"<<endl
<<" 6 简单选择排序"<<endl
<<" 7 堆排序"<<endl
<<endl;
cout<<" 8 归并排序"<<endl
<<" 9 基数排序"<<endl
<<" 0 退出程序"<<endl;
cout<<"请选择主菜单:";
}
// 主函数
int main()
{
int n;
system("cls"); // 清屏
int choice;
do
{
dispmenu(); // 显示主菜单
cout<<endl;
cout<<"Enter choice(1~10,0 退出):";
cin>>choice;
switch(choice)
{
case 1: // 直接插入排序
{
cout<<"直接插入排序"<<endl;
cout<<endl;
n=8;
int R[9];
CopyData(IA,n,R); // IA[]-->R
cout<<"初始序列"<<'\t'; // 显示初始序列
DispData(R,n);
InsertSort(R,n); // 直接插入排序
;
break;
}
case 2: // 折半插入排序
{
cout<<"折半插入排序"<<endl;
cout<<endl;
n=8;
int R[9];
CopyData(IA,n,R); // IA[]-->R
cout<<"初始序列"<<'\t'; // 显示初始序列
DispData(R,n);
BInsertSort(R,n); // 折半插入排序
cout<<endl;
break;
}
case 3: // 希尔排序
{
cout<<"希尔排序"<<endl;
cout<<endl;
int d[3]={5,3,1}; // d值
n=10;
int R[11];
CopyData(SA,n,R); // SA[]-->R[]
cout<<"初始序列"<<'\t';
DispData(R,n); // 显示初始序列
ShellSort(R,n,d,3); // 希尔排序
break;
}
case 4: // 冒泡排序
{
cout<<"冒泡排序"<<endl;
cout<<endl;
n=8;
int R[9];
CopyData(BA,n,R); // BA[]-->R[]
cout<<"初始序列"<<'\t'; // 显示初始序列
DispData(R,n);
Bubble_Sort(R,n); // 冒泡排序
break;
}
case 5: // 快速排序
{
cout<<"快速排序"<<endl;
cout<<endl;
//n=sizeof(QA)/sizeof(QA[0]);
n=8;
int R[9];
CopyData(QA,n,R); // QA[]-->R[]
cout<<"初始序列"<<'\t'; // 显示初始序列
DispData(R,n);
QSort(R,1,n); // 快速排序
cout<<endl;
cout<<"有序序列\t";
DispData(R,n); // 排序结果
break;
}
case 6: // 简单选择排序
{
cout<<"简单选择排序"<<endl;
cout<<endl;
n=8;
int R[9];
CopyData(SSA,n,R); // SSA[]-->R[]
cout<<"初始序列"<<'\t'; // 显示初始序列
DispData(R,n);
SelectSort(R,n); // 简单选择排序
break;
}
case 7: // 堆排序
{
cout<<"堆排序"<<endl;
cout<<endl;
n=8;
int R[9];
CopyData(HA,n,R); // HA[]-->R[]
cout<<"初始序列"<<'\t'; // 显示初始序列
DispData(R,n);
HeapSort(R,n); // 堆排序
cout<<endl;
break;
}
case 8: // 二路归并排序
{
int n1,n2;
cout<<endl;
cout<<"归并排序(非递归)"<<endl; // 二路归非递归并排序
cout<<endl;
n1=7;
int R1[8];
CopyData(EA1,n1,R1); // EA1-->R1
cout<<"初始序列"<<'\t'; // 显示初始序列
DispData(R1,n1);
MergeSort(R1,n1); // 二路归递归并排序
cout<<"归并排序(递归)"<<endl;
cout<<endl;
n2=8;
int R2[9];
CopyData(EA2,n2,R2); // EA2-->R2
cout<<"初始序列"<<'\t'; // 显示初始序列
DispData(R2,n2);
MergeSort1(R2,n2);
cout<<"有序序列\t";
DispData(R2,n2); // 排序结果
break;
}
case 9: // 基数排序
{
int r,d;
r=10; // 十进制数
d=3; // 3个关键字
RNode *L; // 链式存储,无头结点
L=NULL; // 空表
cout<<"基排序"<<endl;
cout<<endl;
n=8;
int R[9];
CopyData(RA,n,R); // RA-->R
cout<<"测试数据:";
DispData(R,n); // 显示初始序列
CreateDL(L,R,n); // 创建链表
cout<<"初始序列"<<'\t'; // 显示链表
DispDL(L);
RadixSort(L,r,d); // 基数排序
cout<<"有序序列\t"; // 显示排序结果
DispDL(L);
break;
}
case 0://退出
;
cout<<"结束运行"<<endl;
break;
default://非法选择
cout<<"Invalid choice\n";
break;
}
}while(choice!=0);
return 0;
}

519
OrigFiles/8-排序/sort.h Normal file
View File

@@ -0,0 +1,519 @@
//第十章 内部排序
//
//一1插入排序
void InsertSort(SqList<type> & L)
{//对顺序表L作直接插入排序
for(int i=2;i<=L.length;i++)
if(L.key[i]<=L.key[i-1])//"<"需将L.key[i]插入有序子表
{
L.key[0]=L.key[i];//复制为哨兵
L.key[i]=L.key[i-1];
for(int j=i-2;L.key[0]<=L.key[j];--j)
L.key[j+1]=L.key[j];//记录后移
L.key[j+1]=L.key[0];//插入到正确位置
}
}
//2折半插入排序
template<class type>
void BInsertSort(SqList<type> &L)
{//对顺序表L作折半插入排序
int high,low,m;
for(int i=2;i<=L.length;i++)
{
L.key[0]=L.key[i];//将L.key[i]暂存到L.key[0]
low=1;
high=i-1;
while(low<=high)//在key[low]到key[high]中折半查找有序插入的位置
{
m=(low+high)/2;//折半
if(L.key[0]<=L.key[m])
high=m-1;//插入低半区
else
low=m+1;//插入高半区
}
for(int j=i-1;j>=high+1;--j)
L.key[j+1]=L.key[j]; //记录后移
L.key[high+1]=L.key[0]; //插入
}
}
//(3)表插入排序
const int SIZE=100;//静态链表最大容量
const int MAXINT=10000;
template<class type>
struct StaListNode{
type data;//记录项
int next;//指针项
};
template<class type>
class StaticList{
public:
StaListNode<type> node[SIZE];
int curlen;//链表实际长度
StaticList()//构造函数
{
cout<<"建立静态链表"<<endl;
cout<<"请输入静态链表的实际长度:"<<endl;
cin>>curlen;
cout<<"请输入各结点数据:"<<endl;
node[0].data=MAXINT;
node[0].next=0;
for(int i=1;i<=curlen;i++)
{
node[i].next=0;
cin>>node[i].data;
}
}
~StaticList()//析构函数
{
}
};
void StaListInsertSort()
{
StaticList<int> sl;
int min,max;//标记最大值最小值
sl.node[0].next=1;
sl.node[1].next=0;//初始化形成只有头结点的循环链表
max=min=1;
for(int i=2;i<=sl.curlen;i++)//向有序循环链表中加入结点共n-1趟
{
if(sl.node[i].data<=sl.node[min].data)
{
sl.node[0].next=i;
sl.node[i].next=i-1;
min=i;
}
if(sl.node[i].data>=sl.node[max].data)
{
sl.node[i].next=0;
sl.node[max].next=i;
max=i;
}
if(sl.node[i].data<sl.node[max].data&&sl.node[i].data>sl.node[min].data)
{
int index1=min,index2;//index2用来标记index1的前一个下标
while(sl.node[i].data>=sl.node[index1].data)
{
index2=index1;
index1=sl.node[index1].next;
}
sl.node[i].next=index1;
sl.node[index2].next=i;
}
}
cout<<"表插入排序结果如下:"<<endl;
int index=sl.node[0].next;
while(index!=0)
{
cout<<sl.node[index].data<<"\t";
index=sl.node[index].next;
}
cout<<endl;
}
//(4)希尔排序
template<class type>
void ShellInsert(SqList<type> &L,int dk)
{//对顺序表进行一趟希尔插入排序
for(int i=dk+1;i<=L.length;i++)
if(L.key[i]<=L.key[i-dk])
{
L.key[0]=L.key[i];
for(int j=i-dk;j>0&&L.key[0]<=L.key[j];j-=dk)
L.key[j+dk]=L.key[j];
L.key[j+dk]=L.key[0];
}
}
template<class type>
void ShellSort(SqList<type> &L,int dlta[],int t)
{
//按增量序列dl[0]--dl[t-1]对顺序表L作哈希排序
for(int k=0;k<t;k++)
ShellInsert(L,dlta[k]);
}
//二快速排序
//1起泡排序
template<class type>
void BubbleSort(SqList<type> & L)
{
for(int i=1;i<L.length;i++)//用i控制比较趟数共n-1趟
{
type t;
for(int j=1;j<=L.length-i;j++)
if(L.key[j]>L.key[j+1])
{
t=L.key[j];
L.key[j]=L.key[j+1];
L.key[j+1]=t;
}
}
}
//(2)快速排序
template<class type>
int Partition(SqList<type>& L,int low,int high)
{//交换顺序表L中子表key[low]--key[high]中的记录,枢轴记录到位,并返回其所在位置,
//此时在它之前(后)的记录均不大(小)于它
type pivotkey;
L.key[0]=L.key[low];//用子表的第一个记录作枢轴记录
pivotkey=L.key[low];//关键字
while(low<high)//从表的两端交替向中间扫描
{
while(low<high&&L.key[high]>=pivotkey) --high;
L.key[low]=L.key[high];//将比枢轴小的记录移至低端
while(low<high&&L.key[low]<=pivotkey) ++low;
L.key[high]=L.key[low];//将比枢轴大的记录移至高端
}
L.key[low]=L.key[0];//枢轴记录到位
return low;//返回枢轴位置
}
template<class type>
void QSort(SqList<type>& L,int low,int high)
{
int mid;//接收枢轴位置
if(low<high)
{
mid=Partition(L,low,high);
QSort(L,low,mid-1);//对低子表进行排序
QSort(L,mid+1,high);//对高子表进行排序
}
}
template<class type>
void QuitSort(SqList<type>& L)//对顺序表进行快速排序
{
QSort(L,1,L.length);
}
//三选择排序
//(1)简单选择排序
template<class type>
int SelectMinKey(SqList<type>& L,int n)
{
int min=n;
type minkey;//最小值
minkey=L.key[n];
for(int i=n+1;i<=L.length;i++)
if(L.key[i]<minkey)
{
minkey=L.key[i];
min=i;
}
return min;
}
template<class type>
void SelectSort(SqList<type>& L)
{
//对顺序表L作简单选择排序
int j;
type t;
for(int i=1;i<=L.length;i++)
{
j=SelectMinKey(L,i);//在L.key[i]--L.key[L.length]中选择最小的记录并将其地址赋给j
if(i!=j)//交换记录
{
t=L.key[i];
L.key[i]=L.key[j];
L.key[j]=t;
}
}
}
//(2)树形选择排序
template<class type>
class TreeNode{
public:
type data;//结点数据值
int index;//树中位置
int active;//是否继续比较标志
TreeNode<type>& operator=(TreeNode<type>& treenode)
{
this->data=treenode.data;
this->index=treenode.index;
this->active=treenode.active;
return *this;
}
};
template<class type>
void ChangeTree(TreeNode<type>*tree,int i)
{
if(i%2==0)
tree[(i-1)/2]=tree[i-1];//当i为偶数时和左结点比较
else
tree[(i-1)/2]=tree[i+1];//当i为奇数时和右结点比较
i=(i-1)/2;//重新比较i上升到父亲结点位置
int j;
while(i)
{
if(i%2==0)//确定i的比较结点位置
j=i-1;
else
j=i+1;
if(!tree[i].active||!tree[j].active)
if(tree[i].active)
tree[(i-1)/2]=tree[i];
else
tree[(i-1)/2]=tree[j];
else
if(tree[i].data<tree[j].data)
tree[(i-1)/2]=tree[i];
else
tree[(i-1)/2]=tree[j];
i=(i-1)/2;
}
}
int Power(int n)//计算2的n次方
{
int result=1;
if(n>=1)
{
for(int i=1;i<=n;i++)
result*=2;
return result;
}
else
return 1;
}
int LeapNum(int n)//计算满足满二叉树的叶子结点总数
{
for(int i=1;i<100;i++)
if(Power(i-1)<n&&n<Power(i))
return Power(i);
else if(Power(i-1)==n)
return Power(i-1);
}
template<class type>
void TreeSort(type a[],int n)
{//本排序方法只适用于满二叉树
TreeNode<type>* tree;
int bottsize=LeapNum(n);//树底层结点个数,此处必须满足满二叉树
int size=2*bottsize-1;//树中结点总数
int externalindex=bottsize-1;//开始进行比较的结点位置
tree=new TreeNode<type>[size];
assert(tree);
int j=0;
for(int i=externalindex;i<size;i++)
{
tree[i].index=i;//下标赋值
if(j<n)
{
tree[i].active=1;//设置访问标志。可以访问
tree[i].data=a[j++];//载入数据
}
else
tree[i].active=0;//额外结点设置成active=0
}
i=externalindex;
while(i)//比较找到最小结点
{
j=i;
while(j<2*i)
{
if(!tree[j+1].active||tree[j].data<=tree[j+1].data)
{
if(!tree[j+1].active&&!tree[j].active)
tree[(j-1)/2].active=0;//其孩子结点都是额外结点的结点不可访问
tree[(j-1)/2]=tree[j];//较小结点赋值给其双亲结点
}
else
tree[(j-1)/2]=tree[j+1];
j+=2;
}
i=(i-1)/2;
}
for(i=0;i<n-1;i++)//处理前面n-1个结点
{
a[i]=tree[0].data;
tree[tree[0].index].active=0;//不在参加比较
ChangeTree(tree,tree[0].index);//修改树结构
}
a[n-1]=tree[0].data;//处理数值最大的结点
}
template<class type>
void OutPut(type a[],int n)//输出函数
{
for(int i=0;i<n;i++)
cout<<a[i]<<"\t";
cout<<endl;
}
//堆排序
template<class type>
void HeapAdjust(SqList<type>& L,int s,int m)
{//对顺序表做查找,从值最大的孩子结点向下筛选,找到最大值
type rc=L.key[s];
for(int j=2*s;j<=m;j*=2)
{
if(j<m&&L.key[j]<=L.key[j+1])//找到值相对较大的孩子结点,并依次向下筛选
j++;
if(rc>L.key[j]) break;//如果rc最大则推出while循环
L.key[s]=L.key[j];//最大值赋值
s=j;//交换位置
}
L.key[s]=rc;
}
template<class type>
void HeapSort(SqList<type>& L)
{//对顺序表L进行堆排序
type value;
for(int i=L.length/2;i>0;i--)//把L.key[1...L.length]调整为大顶堆
HeapAdjust(L,i,L.length);
for(i=L.length;i>1;--i)
{
value=L.key[1];
L.key[1]=L.key[i];
L.key[i]=value;
HeapAdjust(L,1,i-1);//将L.key[1...i-1]重新调整为大顶堆
}
}
//四
//归并排序
template<class type>
void Merge(type *SR,type *TR,int i,int m,int n)
{//将有序的SR[i...m]和SR[m+1...n]归并为有序的TR[i...n]
for(int j=m+1,k=i;i<=m&&j<=n;k++)//将SR中的记录由大到小并入TR
{
if(SR[i]<=SR[j])
TR[k]=SR[i++];
else
TR[k]=SR[j++];
}
if(i<=m)//将剩余的SR[i...m]赋值到TR
for(int a=i;a<=m;a++)
TR[k++]=SR[a];
else if(j<=n)//将剩余的SR[j...n]复制到TR
for(int b=j;b<=n;b++)
TR[k++]=SR[b];
}
template<class type>
void MSort(type *SR,type *TR1,int s,int t)
{
type TR2[100];//数组大小可以根据实际情况重新定义
int m;
//将SR[s...t]归并排序为TR[s...t]
if(s==t)
TR1[s]=SR[s];
else
{
m=(s+t)/2;//将SR[s...t]平分为SR[s...m]和SR[m+1...t]
MSort(SR,TR2,s,m);//递归地将SR[s...m]归并为有序的TR2[s...m]
MSort(SR,TR2,m+1,t);//递归地将SR[m+1...t]归并为TR2[m+1...t]
Merge(TR2,TR1,s,m,t);//将TR2[s...m]和TR2[m+1...t]归并到TR1[s...t]
}
}
template<class type>
void MergeSort(SqList<type> &L)
{//对顺序表L作归并排序
MSort(L.key,L.key,1,L.length);
}
//五 基数排序
//链式基数排序
const RADIX=10;
typedef int ArrType[RADIX];
ArrType f,e;
template<class type>
struct SLCell{
type *keys;
int next;
};
template<class type>
struct SLList{
SLCell<type>* SList;
int keynum;
int recnum;
};
template<class type>
void InitSLList(SLList<type>& SL)//创建静态链表
{
cout<<"建立静态链表"<<endl<<"请输入数据个数:"<<endl;
cin>>SL.recnum;
SL.SList=new SLCell<type>[SL.recnum+1];
assert(SL.SList);
cout<<"请输入关键字项数"<<endl;
cin>>SL.keynum;
for(int i=1;i<=SL.recnum;i++)
{
SL.SList[i].keys=new type[SL.keynum+1];
assert(SL.SList[i].keys);
}
SL.SList[0].next=1;
cout<<"请输入数据"<<endl;
for(i=1;i<=SL.recnum;i++)
{
cout<<"请输入第"<<i<<"个数据"<<endl;
for(int j=1;j<=SL.keynum;j++)
cin>>SL.SList[i].keys[j];
if(i!=SL.recnum)
SL.SList[i].next=i+1;
else
SL.SList[i].next=0;
}
}
template<class type>
void RelList(SLList<type> &SL)//释放内存空间
{
for(int i=1;i<=SL.recnum;i++)
delete SL.SList[i].keys;
delete SL.SList;
}
template<class type>
void OutPut(SLList<type>& SL)//输出静态链表
{
for(int i=SL.SList[0].next;i;i=SL.SList[i].next)
{
//cout<<i<<endl;
for(int j=1;j<=SL.keynum;j++)
cout<<SL.SList[i].keys[j];
cout<<'\t';
}
cout<<endl;
}
template<class type>
void Distrbute(SLCell<type>* r,int i,ArrType &f,ArrType& e)
{//按第i个关键字keys[i]建立RADIX个子表使同一子表中记录的keys[i]相同
//f[0...RADIX]和e[0...RADIX]分别指向各个子表中第一个和最后一个记录
int j;
for(j=0;j<RADIX;j++)//各子表初始化为空
f[j]=0;
for(int a=r[0].next;a;a=r[a].next)
{
j=r[a].keys[i];
if(!f[j])
f[j]=a;
else
r[e[j]].next=a;
e[j]=a;
}
}
template<class type>
void Collect(SLCell<type>* r,int i,ArrType &f,ArrType& e)
{//按keys[i]自小至大将f[0...RADIX]所指各个子表依次链接成一个链表
int j;
for( j=0;!f[j];j++);//找第一个非空子表
r[0].next=f[j];//r[0].next指向第一个非空子表中第一个结点
int t=e[j];
while(j<RADIX)
{
for(j++;j<RADIX-1&&!f[j];j++);//找下一个非空子表
if(f[j])
{r[t].next=f[j];t=e[j];}//链接两个非空子表
}
r[t].next=0;//t指向最后一个非空子表中的左后一个结点
}
template<class type>
void RadixSort(SLList<type> &SL)
{//对L作基数排序使得L按关键字自小到大有序
for(int i=SL.keynum;i>=1;i--)//按最高位优先依次对各关键字进行分配和收集
{
Distrbute(SL.SList,i,f,e);//第i趟分配
Collect(SL.SList,i,f,e);//第i趟收集
}
}