数据结构查找排序代码部分总结
折半查找和顺序查找
三种简单排序
冒泡排序
//冒泡排序
void BubblSort(int arr[],int length)
{
for(int i=0; i<length-1; i++)
{
for(int j=0; j<length-i; j++)
{
if(arr[j]>arr[j+1])
{
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
}
选择排序
//选择排序
void SelectSort(int arr[],int length)
{
while(length>1)
{
int Count=findMax(arr,length);
int temp=arr[Count];
arr[Count]=arr[length-1];
arr[length-1]=temp;
length--;
}
}
插入排序
//插入排序
void Insert(int arr[],int n)
{
int key=arr[n];
int i=n;
while(key<arr[i-1])
{
arr[i]=arr[i-1];
i--;
if(i==0)
{
break;
}
}
arr[i]=key;
}
void InsertSort(int arr[],int length)
{
for(int i=1;i<length;i++)
{
Insert(arr,i);
}
}
完整代码
#include <iostream>
using namespace std;
template <typename T>//类模板 用来自适应传入形参的类型
//获取数组长度
int length(T& arr)
{
return sizeof(arr)/sizeof(arr[0]);
}
//冒泡排序
void BubblSort(int arr[],int length)
{
for(int i=0; i<length-1; i++)
{
for(int j=0; j<length-i; j++)
{
if(arr[j]>arr[j+1])
{
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
}
//寻找最大值
int findMax(int arr[],int length)
{
int Max=arr[0];
int Count;
for(int i=0;i<length;i++)
{
if(arr[i]>=Max)
{
Max=arr[i];
Count=i;
}
}
return Count;
}
//选择排序
void SelectSort(int arr[],int length)
{
while(length>1)
{
int Count=findMax(arr,length);
int temp=arr[Count];
arr[Count]=arr[length-1];
arr[length-1]=temp;
length--;
}
}
//插入排序
void Insert(int arr[],int n)
{
int key=arr[n];
int i=n;
while(key<arr[i-1])
{
arr[i]=arr[i-1];
i--;
if(i==0)
{
break;
}
}
arr[i]=key;
}
void InsertSort(int arr[],int length)
{
for(int i=1;i<length;i++)
{
Insert(arr,i);
}
}
int main()
{
int arr[]= {5,6,0,2,1,9};
SelectSort(arr,length(arr));
cout<<length(arr)<<endl;
for(int i=0;i<length(arr);i++)
{
cout<<arr[i]<<" ";
}
return 0;
}
折半查找和顺序查找
折半查找
//折半查找(只能顺序表,因为顺序表可以随机存储)
int BinarySearch(int arr[],int length,int e)
{
int index=-1;
int low=0;
int high=length-1;
while(low<=high)
{
int Mid=(low+high)/2;
if(arr[Mid]>e)
{
high=Mid-1;
}
if(arr[Mid]<e)
{
low=Mid+1;
}
if(arr[Mid]==e)
{
index=Mid;
break;
}
}
return index;
}
顺序查找
//顺序查找(顺序表链表都可)
int Search(int arr[],int length,int e)
{
int index=-1;
for(int i=0; i<length; i++)
{
if(arr[i]==e)
{
index=i;
}
}
return index;//注:这里并没有实现数组中出现相同元素时,循环输出位置
}
完整代码
#include <iostream>
/*
本代码仅仅为两种查找方式的思想,做题时应结合顺序表链表和树的结构定义
写出对应类型的代码
*/
using namespace std;
template<typename T>
int getLength(T& arr)
{
return sizeof(arr)/sizeof(arr[0]);
}
//顺序查找(顺序表链表都可)
int Search(int arr[],int length,int e)
{
int index=-1;
for(int i=0; i<length; i++)
{
if(arr[i]==e)
{
index=i;
}
}
return index;//注:这里并没有实现数组中出现相同元素时,循环输出位置
}
//折半查找(只能顺序表,因为顺序表可以随机存储)
int BinarySearch(int arr[],int length,int e)
{
int index=-1;
int low=0;
int high=length-1;
while(low<=high)
{
int Mid=(low+high)/2;
if(arr[Mid]>e)
{
high=Mid-1;
}
if(arr[Mid]<e)
{
low=Mid+1;
}
if(arr[Mid]==e)
{
index=Mid;
break;
}
}
return index;
}
int main()
{
int arr[]= {11,22,55,57,64,67,97,99};
cout<<Search(arr,getLength(arr),99);
return 0;
}
希尔排序和折半插入排序
希尔排序
//希尔排序
void ShellSort(int arr[],int n)
{
for(int d=n/2;d>=1;d/=2)
{
for(int i=d;i<n;i++)
{
if(arr[i-d]>arr[i])
{
int j;
int temp=arr[i];
for(j=i-d;j>=0&&arr[j]>temp;j-=d)
{
arr[j+d]=arr[j];
}
arr[j+d]=temp;
}
}
}
}
折半插入排序
//折半插入排序
void BinaryInsertSort(int arr[],int n)
{
for(int i=1; i<n; i++)
{
int key=arr[i];
int Left=0;
int Right=i-1;
while(Left<=Right)
{
int Mid=(Right+Left)/2;
if(arr[Mid]<key)
{
Left=Mid+1;
}
else
{
Right=Mid-1;
}
}
for(int j=i-1; j>Right; j--)
{
arr[j+1]=arr[j];
}
arr[Right+1]=key;
}
}
完整代码
#include <iostream>
using namespace std;
template<typename T>
//获取数组长度
/*这里为什么加引用(普通函数里数组会退化成指针,传的是数组地址。
模板函数里加上‘&’后就可以把整个数组传进来了)
*/
int getLength(T& arr)
{
return sizeof(arr)/sizeof(arr[0]);
}
//折半插入排序
void BinaryInsertSort(int arr[],int n)
{
for(int i=1; i<n; i++)
{
int key=arr[i];
int Left=0;
int Right=i-1;
while(Left<=Right)
{
int Mid=(Right+Left)/2;
if(arr[Mid]<key)
{
Left=Mid+1; }
else
{
Right=Mid-1;
}
}
for(int j=i-1; j>Right; j--)
{
arr[j+1]=arr[j];
}
arr[Right+1]=key;
}
}
//希尔排序
/*
函数内千万不能调用getlength函数,因为数组在是以地址的方式传进
普通函数内的,所以根本得不到数组的长度
简而言之:普通函数内的数组不能使用sizeof
*/
void ShellSort(int arr[],int n)
{
for(int d=n/2;d>=1;d/=2)
{
for(int i=d;i<n;i++)
{
if(arr[i-d]>arr[i])
{
int j;
int temp=arr[i];
for(j=i-d;j>=0&&arr[j]>temp;j-=d)
{
arr[j+d]=arr[j];
}
arr[j+d]=temp;
}
}
}
}
int main()
{
int arr[]= {7,5,4,9,8,2,6};
ShellSort(arr,getLength(arr));
for(int i=0; i<getLength(arr); i++)
{
cout<<arr[i]<<" ";
}
return 0;
}
快速排序(qSort)
#include <iostream>
#include <stdlib.h>
using namespace std;
/*
特别注意:以下代码注释中指代的“指针”并非真正的指针,本质为数组下标。
但因C++中数组传参的特殊性(数组在函数传参时默认传的是地址,并非整个数组。如
果想在函数中得到整个数组,则需在函数中额外定义一个数组,然后挨个赋值)因此
在函数中传递数组时,只需加数组符号,不需要加引用“&”即可达到引用参数的效果
在目前来写代码的用法中,数组传参和用指针传参效果其实是一样的(用法不一样,
数组“.”,指针“->”),不一样的地方是关于内存分配,此处不为考试内容,故了解即可。
*/
template<typename T>
//获取数组长度
int getLength(T& arr)
{
return sizeof(arr)/sizeof(arr[0]);
}
//找第一次“中分”
int getMid(int arr[],int Left,int Right)
{
int pivot=arr[Left];
while(Left<Right)
{
while(arr[Right]>pivot&&Left<Right)
Right--;
arr[Left]=arr[Right];
while(arr[Left]<pivot&&Left<Right)
Left++;
arr[Right]=arr[Left];
}
//当左指针和右指针相遇时,第一次排序结束
arr[Left]=pivot;
return Left;
}
//快速排序——递归
void qSort(int arr[],int Left,int Right)
{
if(Left<Right)//当左指针大于或等于右指针时,递归结束
{
int Mid=getMid(arr,Left,Right);
qSort(arr,Left,Mid-1);
qSort(arr,Mid+1,Right);
}
}
int main()
{
int arr[]= {9,8,4,5,2,3,1};
qSort(arr,0,getLength(arr)-1);
for(int i =0; i<getLength(arr); i++)
{
cout<<arr[i]<<" ";
}
return 0;
}
归并排序(mergeSort)
#include <iostream>
#include <stdlib.h>
#define Elemtype int
using namespace std;
void mergeTry(Elemtype arr[],int l,int m,int r)
{
int left_MAX=m-l;
int right_MAX=r-m+1;
int i,j,k;
Elemtype * left= (Elemtype *)malloc(left_MAX*sizeof(Elemtype));
Elemtype * right=(Elemtype *)malloc(right_MAX*sizeof(Elemtype));
for(i = l;i<m;i++)
{
left[i-l] = arr[i];
}
for(i = m;i<=r;i++)
{
right[i-m]=arr[i];
}
i=0,j=0,k=l;
while(i<left_MAX&&j<right_MAX)
{
if(left[i]<right[j])
{
arr[k]=left[i];
i++;
k++;
}
else
{
arr[k]=right[j];
j++;
k++;
}
}
while(i<left_MAX)
{
arr[k]=left[i];
i++;
k++;
}
while(j<right_MAX)
{
arr[k]=right[j];
j++;
k++;
}
}
void mergeSort(Elemtype arr[],int l,int r)
{
if(l==r)
{
return;
}
else{
int m=(r+l)/2;
mergeSort(arr,l,m);
mergeSort(arr,m+1,r);
mergeTry(arr,l,m+1,r);
}
}
int main()
{
Elemtype arr[]={2,5,6,9,8,1,3,4};
mergeSort(arr,0,7);
for(int i = 0;i<8;i++)
{
cout<<arr[i]<<endl;
}
return 0;
}
大小根堆
大根堆(HeapSort)
#include <iostream>
using namespace std;
//数组内关键字交换
void swapTry(int tree[],int i ,int Max)
{
int temp=tree[i];
tree[i]=tree[Max];
tree[Max]=temp;
}
//父节点的关键值替换为最大
void heapify(int tree[],int n ,int i)
{
if(i>=n) return;
int CLeft=2*i+1;
int CRight=2*i+2;
int Max=i;
if(CLeft<n&&tree[CLeft]>tree[Max])
Max=CLeft;
if(CRight<n&&tree[CRight]>tree[Max])
Max=CRight;
if(Max!=i)
{
swapTry(tree,i,Max);
heapify(tree,n,Max);
}
}
//构造大根堆
void buildHeapify(int tree[],int n)
{
for(int i=n-1;i>=0;i--)
{
int parent=(i-1)/2;
heapify(tree,n,parent);
}
}
//堆排序
void heapifySort(int tree[],int n)
{
for(int i= n-1;i>=0;i--)
{
buildHeapify(tree,i+1);
swapTry(tree,0,i);
}
}
int main()
{
int tree[]={1,3,4,7,9,5,97,31,41};
heapifySort(tree,9);
for(int i = 0; i<9;i++)
{
cout<<tree[i]<<endl;
}
return 0;
}
小根堆(LittleHeapSort)
注意:这里小根堆结果是逆序输出的递增序列。
#include <iostream>
using namespace std;
//交换元素
void swapTry(int tree[],int i,int Min)
{
int temp=tree[i];
tree[i]=tree[Min];
tree[Min]=temp;
}
//找出根节点最小
void heapify(int tree[],int n,int i)
{
if(i>=n) return;
//int parent = (i-1)/2;
int CLeft=2*i+1;
int CRight=2*i+2;
int Min=i;
if(tree[CLeft]<tree[Min]&&CLeft<n)
Min=CLeft;
if(tree[CRight]<tree[Min]&&CRight<n)
Min=CRight;
if(i!=Min)
{
swapTry(tree,i ,Min);
heapify(tree,n,Min);
}
}
//建立小根堆
void buildHeapify(int tree[],int n)
{
for(int i = n-1;i>=0;i--)
{
int parent=(i-1)/2;
heapify(tree,n,parent);
}
}
//小根堆排序
void heapifySort(int tree[],int n)
{
for(int i = n-1;i>=0;i--)
{
buildHeapify(tree,i+1);
swapTry(tree,0,i);
}
//数组逆序,从小到大
int p=0,q=n-1;
while(p<q)
{
swapTry(tree,p,q);
p++;
q--;
}
}
int main()
{
int tree[]={11,88,33,55,22};
heapifySort(tree,5);
for(int i = 0; i<5;i++)
{
cout<<tree[i]<<endl;
}
return 0;
}