学习用,记录数据结构代码
8-13
排序的各种408会考的代码的手动实现
(麻了,写成查找了,也都没实现查找的代码)
------------------------------------8-17 复习代码更新-----------------------------
8-17 复习代码时,发现插入排序算法有问题。
修改后如下(自己写的)
void InsertSort(int a[],int n)
{
for(int i=1;i<n;i++)
{
int t=i;
for(int j=i-1;j>=0&&a[j]>a[t];--j)
{
swap(a[j],a[t]);
t=j;
}
}
}
---------------------------------------------分割线--------------------------------------------
#include <bits/stdc++.h>
using namespace std;
#define maxn 0xfffff
//8.17发现错误,最终a[i]的位置应该是j+1,
//j已经是小于a[i]的数了,你不能去占人家的位置,
void InsertSort1(int a[],int n)//纯插入
{
int i,j,temp;
for(i=1;i<n;i++)
{
if(a[i-1]>a[i])
{
temp = a[i];
for(j=i-1;a[j]>temp&&j>=0;--j) a[j+1] = a[j];
a[j+1]=temp;
//a[j] = temp;
//8.17发现错误,最终a[i]的位置应该是j+1,
//j已经是小于a[i]的数了,你不能去占人家的位置,
}
}
}//复习时调用无法生效。
void InsertSort2(int a[],int n)//插入+二分
{
int i,j,temp,low,high,mid;
for(i=1;i<n;++i)
{
temp = a[i]; low=0; high=i-1;
while(low<=high)
{
mid=(low+high)/2;
if(a[mid]>temp) high=mid-1;
else low=mid+1;
}
for(j=i-1;j>=low;--j) a[j+1]=a[j];
a[low]=temp;
}
}
void BubbleSort(int a[],int n)//与之前自己想的冒泡排序有不同,算是升级版
{
for(int i=0;i<n-1;i++)
{
bool ischanged=false;
for(int j=n-1;j>i;--j)
if(a[j-1]>a[j])
{
swap(a[j],a[i]);
ischanged=true;
}
if(!ischanged) return;
}
}
8.17更新,ShellSort问题同InsertSort1相同,都是a[i]的最终位置确定的问题。
void ShellSort(int a[],int n)
{
int i,j,d,temp;
for(d=n/2;d>=1;d/=2)
{
for(i=d;i<n;++i)
{
if(a[i-d]>a[i])
{
temp=a[i];
for(j=i-d;j>=0&&a[j]>temp;j-=d) a[j+d]=a[j];
a[j+d]=temp;
//a[j]=temp;
//
}
}
}
}
int Partition(int a[],int low,int high)//将数组a[]划分成两个部分
{
int pivot = a[low],lef=low,rig=high;
while(lef<rig)
{
while(lef<rig&&a[rig]>=pivot) --rig;
a[lef]=a[rig];
while(lef<rig&&a[lef]<pivot ) ++lef;
a[rig]=a[lef];
}
a[lef]=pivot;
return lef;
}
void QuickSort(int a[],int low,int high)
{
if(low>=high) return;
int pivotpos = Partition(a,low,high);
QuickSort(a,low,pivotpos-1);
QuickSort(a,pivotpos+1,high);
}
void HeadHugeAdjust(int a[],int k,int len)
{
a[0]=a[k]; //k变量的作用:保存初值,以及i的初始化,下沉的时候,其实是在利用i进行下沉,k始终指向子大根堆的堆顶。
for(int i=2*k;i<=len;i*=2)//i*=2,即往左子树走,之后会有和右子树比较的所以,意思就是走向子树。
{
if(i<len&&a[i+1]>a[i]) ++i;
if(a[0]>=a[i]) break;//没发生过交换,也就是说是♂大根了(因为是自底向上,所以就用考虑下层的结点了。)
else
{
a[k]=a[i]; //大根向上走
k=i; //k指向交换后的子大根堆顶(错了),这里并没有交换ak下来,因为每次在比较的时候都是用a[0]比较,而不是A[K]
}
}
a[k]=a[0];
}
void HeadTinyAdjust(int a[],int k,int len)//给定堆顶点,把他整理成小根堆。
{
a[0]=a[k];
for(int i=k*2;i<=len;i*=2)
{
if(a[i+1]<a[i]&&i<len) ++i;
if(a[0]<=a[i]) break;
else
{
a[k]=a[i];
k=i;
a[k]=a[0];
}
}
a[k]=a[0];
}
void BuildHugeDickHeap(int a[],int len){ for(int j=len/2;j>=0;--j) HeadHugeAdjust(a,j,len);/*or HeadTinyAdjust()*/}
//从后往前调整所有非终端结点;len/2就是最后一个非叶分支结点。
void HeapSort(int a[],int len)
{
BuildHugeDickHeap(a,len);
for(int i=len;i>=1;--i)
{
swap(a[i],a[1]);//下坠大根
HeadHugeAdjust(a,1,i);
}
}
void Merge(int a[],int low,int mid,int high)
{
int i,p1=low,p2=mid+1,*b=new int[maxn];
for(int j=low;j<=high;++j)
b[j]=a[j];
for(i=low;p1<=mid&&p2<=high;++i)
{
if(b[p1]<=b[p2]) a[i]=b[p1++];
else a[i]=b[p2++];
}
while(p1<=mid) a[i++]=b[p1++];
while(p2<=high) a[i++]=b[p2++];
}
void MergeSort(int a[],int low,int high)//merge domain [low,high]
{
if(low>=high) return;
int mid = (low+high)/2;
MergeSort(a,low,mid);
MergeSort(a,mid+1,high);
Merge(a,low,mid,high);
}