# 常用数据结构_排序_查找练习

## 1冒泡排序

#include<stdio.h>
//打印
void print(int r[],int length){
if(r == NULL)return;
int i;
for(i=0;i<length;i++){
printf("%3d",r[i]);
}
printf("\n");
}
//交换 数值
void swap(int r[],int i,int j){
int tmp = r[i];
r[i] = r[j];
r[j] = tmp;
}
//常规冒泡排序
void bubbleSort(int r[],int length){
if(r == NULL || length<=0)return;
int i,j;
for(i=0;i<length;i++){
for(j=length-1;j>i;j--){
if(r[j]<r[j-1]){
int tmp = r[j];
r[j] = r[j-1];
r[j-1] = tmp;
}
}
}
}
//改进冒泡排序添加flag
void bubbleSort1(int r[],int length){
if(r == NULL || length<=0)return ;
int i,j,tmp;
bool flag = true;
for(i=0;i<length && flag;i++){
flag = false;
for(j=length-1;j>i;j--){
if(r[j]<r[j-1]){
tmp = r[j];
r[j] = r[j-1];
r[j-1] = tmp;

flag = true;
}
}
}
}
//改进冒泡排序-双向查找
void bubbleSort2(int r[],int length){
if(r == NULL || length<=0)return;
int low,high;
low = 0;
high = length-1;
while(low<high){
for(int i=low;i<high;i++){ //正向找出每次最大值
if(r[i]>r[i+1])swap(r,i,i+1);
}
high--;
for(int i=high;i>low;i--){
if(r[i]<r[i-1])swap(r,i,i-1);
}
low++;
}

}

int main(){
int r[] = {3,5,9,8,1,4,6,7,2};
print(r,9);
//bubbleSort(r,9); //常规排序
//bubbleSort1(r,9); //添加flag冒泡排序
bubbleSort2(r,9); //双向查找
print(r,9);

return 0;
}


## 2简单选择排序

#include<stdio.h>

//打印
void print(int r[],int length){
if(r==NULL || length<=0)return;
int i = 0;
for(i=0;i<length;i++){
printf("%3d",r[i]);
}
printf("\n");
}

//交换
void swap(int r[],int i,int j){
if(r==NULL || i<0 || j<0)return;
int tmp = r[i];
r[i] = r[j];
r[j] = tmp;
}

//简单选择排序
void selectSort(int r[],int length){
if(r==NULL || length<=0)return;
int i,j,min;
for(i=0;i<length-1;i++){
min = i;
for(j=i+1;j<length;j++){
if(r[j]<r[min]){
min = j;
}
}
if(min != i){
swap(r,i,min);
}
}
}

int main(){
int r[] = {3,5,9,8,1,4,6,7,2};
print(r,9);
selectSort(r,9);
print(r,9);

return 0;
}



## 3直接插入排序

#include<stdio.h>

//打印
void print(int r[],int length){
if(r==NULL || length<=0) return;
int i;
for(i=0;i<length;i++){
printf("%3d",r[i]);
}
printf("\n");
}

//直接插入排序
void insertSort(int r[],int length){
if(r==NULL || length<=0) return ;
int i;
for(i=1;i<length;i++){
if(r[i]<r[i-1]){
int x = r[i];
int j = i-1;
while(x<r[j] && j>=0){
r[j+1] = r[j];
j--;
}
r[j+1] = x;
}
}
}

int main(){
int r[] = {3,5,9,8,1,4,6,7,2};
print(r,9);
insertSort(r,9);
print(r,9);

return 0;
} 

## 4希尔排序

#include<stdio.h>

//打印
void print(int r[],int length){
if(r==NULL || length<=0)return;
int i;
for(i=0;i<length;i++){
printf("%3d",r[i]);
}
printf("\n");
}
//直接插入排序
void insertSort(int r[],int length,int dk){
if(r==NULL || length<=0)return;
int i;
for(i=dk;i<length;i++){
if(r[i]<r[i-dk]){
int x = r[i];
int j = i-dk;
while(x<r[j] && j>=0){
r[j+dk] = r[j];
j = j-dk;
}
r[j+dk] = x;
}
}

}
//希尔排序
void shellSort(int r[],int length){
if(r==NULL || length<=0)return;
int dk = (length-1)/2;
while(dk>=1){
insertSort(r,length,dk);
dk  = dk/2;
}
}

int main(){
int r[] = {3,5,9,8,1,4,6,7,2};
print(r,9);
shellSort(r,9);
print(r,9);

return 0;
}


## 5堆排序

#include<stdio.h>

//打印
void print(int r[],int length){
if(r==NULL || length<=0)return ;
int i = 0;
for(i=0;i<length;i++){
printf("%3d",r[i]);
}
printf("\n");
}
//调整堆（构建大顶堆）
int tmp = r[s]; //当前操作的节点
int child = 2*s+1; //s的左孩子
while(child	<length	){
if(child+1<length && r[child]<r[child+1]){ //找到左右子节点中的最大值
child++;
}
if(r[s]<r[child]){
r[s] = r[child];
s = child;
child = 2*s+1;
}else{ //如果父节点本身就比子节点大则，跳出循环
break;
}
r[s] = tmp;
}
}

//创建堆
void buidHeap(int r[],int length){
int i = 0;
for(i=(length-1)/2;i>=0;i--){
}
}
//堆排序
void heapSort(int r[],int length){
int i,tmp;
buidHeap(r,length); //构建大顶堆
for(i=length-1;i>=0;i--){
int tmp = r[i];
r[i] = r[0];
r[0] = tmp;
}

}

int main(){
int r[] = {3,5,9,8,1,4,6,7,2};
print(r,9);
heapSort(r,9);
print(r,9);

return 0;
} 

## 6归并排序

#include<stdio.h>
typedef int ElemType[10];
//打印
void print(ElemType r,int n){
int i;
for(i=0;i<n;i++){
printf("%3d",r[i]);
}
printf("\n");
}

//合并
void Merge(ElemType	r,ElemType rf, int s,int m,int t){
int i,j,k;
for(j=m+1,i=s,k=s;i<=m && j<=t;k++){
if(r[i]<r[j]){
rf[k] = r[i++];
}else{
rf[k] = r[j++];
}
}
while(i<=m)rf[k++] = r[i++];
while(j<=t)rf[k++] = r[j++];
}

//归并排序
void MSort(ElemType	r,ElemType rf,int s,int t){
ElemType rf2;
if(s==t){
rf[s] = r[s];
}else{
int m = (s+t)/2;
MSort(r,rf2,s,m);
MSort(r,rf2,m+1,t);
Merge(rf2,rf,s,m,t);
}
}

int main(){
ElemType r = {3,1,5,7,2,4,9,6,10,8};
ElemType rf;
printf("排序前：\n");
print(r,10);
printf("归并排序后：\n");
MSort(r,rf,0,9);
print(rf,10);

return 0;
}


## 7快速排序

#include<stdio.h>

typedef int ElemType[10];

//打印
void print(ElemType r,int length){
if(r==NULL || length<=0)return;
int i = 0;
for(i=0;i<length;i++){
printf("%3d",r[i]);
}
printf("\n");
}
//交换
void swap(ElemType r,int low ,int high){
int tmp = r[low];
r[low] = r[high];
r[high] = tmp;
}
//获取枢轴
int partition(ElemType r,int low,int high){
int privotKey = r[low];
while(low<high){
while(low<high && r[high]>=privotKey)high--;
swap(r,low,high);
while(low<high && r[low]<=privotKey)low++;
swap(r,low,high);
}
return low;
}
//快速排序
void QSort(ElemType r,int low,int high){
if(low<high){
int privot = partition(r,low,high);
QSort(r,low,privot-1);
QSort(r,privot+1,high);
}
}

int main(){
ElemType r = {3,1,5,7,2,4,9,6,10,8};

printf("排序前：\n");
print(r,10);
printf("归并排序后：\n");
QSort(r,0,9);
print(r,10);

return 0;
} 

## 二分查找

#include<stdio.h>

typedef int ElemType[10];

//打印
void print(ElemType r,int length){
if(r==NULL || length<=0)return;
int i = 0;
for(i=0;i<length;i++){
printf("%3d",r[i]);
}
printf("\n");
}
//交换
void swap(ElemType r,int low ,int high){
int tmp = r[low];
r[low] = r[high];
r[high] = tmp;
}
//获取枢轴
int partition(ElemType r,int low,int high){
int privotKey = r[low];
while(low<high){
while(low<high && r[high]>=privotKey)high--;
swap(r,low,high);
while(low<high && r[low]<=privotKey)low++;
swap(r,low,high);
}
return low;
}
//快速排序
void QSort(ElemType r,int low,int high){
if(low<high){
int privot = partition(r,low,high);
QSort(r,low,privot-1);
QSort(r,privot+1,high);
}
}
//二分查找
void binSearch(ElemType r,int length,int key){
if(r==NULL || length<=0)return;
int low = 0;
int high = length-1;
while(low<high){
int mid = (low+high)/2;
if(r[mid] == key){
printf("已查找到！\n");
return ;
}else if(r[mid]<key){
low = mid+1;
}else{
high = mid-1;
}
}
printf("未查找到！\n");
}
int main(){
ElemType r = {3,1,5,7,2,4,9,6,10,8};
int key = 6;
printf("排序前：\n");
print(r,10);
printf("归并排序后：\n");
QSort(r,0,9);
print(r,10);
printf("查找元素%d的结果：",key);
binSearch(r,10,key);

return 0;
}


## 递归创建遍历二叉树

#include<stdio.h>
#include<stdlib.h>

typedef struct Node{
int data;
struct Node *lchild;
struct Node *rchild;
}Node,*P_Node;

//创建树
void createTree(P_Node &T){
char data;
scanf("%c",&data);
if(data == '#'){
T = NULL;
return;
}else{
T = (P_Node)malloc(sizeof(Node));
if(T == NULL){
printf("创建树失败!\n");
return;
}
T->data = data;
createTree(T->lchild);
createTree(T->rchild);

}
}
//前序遍历
void preOrderTraversal(P_Node &T){
if(T == NULL){
return ;
}
printf("%3c",T->data);
preOrderTraversal(T->lchild);
preOrderTraversal(T->rchild);
}
//中序遍历
void midOrderTraversal(P_Node T){
if(T == NULL){
return ;
}
midOrderTraversal(T->lchild);
printf("%3c",T->data);
midOrderTraversal(T->rchild);
}
//后序遍历
void afterOrderTraversal(P_Node T){
if(T == NULL){
return ;
}
afterOrderTraversal(T->lchild);
afterOrderTraversal(T->rchild);
printf("%3c",T->data);
}

int main(){
P_Node T;
createTree(T);
printf("\前序遍历：");
preOrderTraversal(T);
printf("\n中序遍历：");
midOrderTraversal(T);
printf("\n后序遍历：");
afterOrderTraversal(T);
printf("\n");
return 0;
}


## 非递归创建遍历二叉树

#include<stdio.h>
#include<stdlib.h>
#include <stack>  //需要引入栈文件

using namespace std;//同时要设置命名空间

typedef struct Node{
char data;
struct Node *lchild;
struct Node *rchild;
}Node,*P_Node;

//创建二叉树树
void createTree(P_Node &T){
char data;
scanf("%c",&data);
if(data == '#'){
T = NULL;
return;
}else{
T = (P_Node)malloc(sizeof(Node));
if(T == NULL){
printf("创建树失败！\n");
exit(-1);
}
T->data = data;
createTree(T->lchild);
createTree(T->rchild);
}
}

//非递归前序遍历二叉树
void preOrderTraversal(P_Node T){
stack<P_Node> Stack;
while(T || !Stack.empty()){
while(T){
printf("%3c",T->data);
Stack.push(T);
T = T->lchild;
}
T = Stack.top();
Stack.pop();
T = T->rchild;
}
}
//非递归中序遍历二叉树
void midOrderTraversal(P_Node T){
stack<P_Node> Stack;
while(T || !Stack.empty()){
while(T){
Stack.push(T);
T = T->lchild;
}
T = Stack.top();
printf("%3c",T->data);
Stack.pop();
T = T->rchild;
}
}
//非递归后序遍历二叉树
void afterOrderTraversal(P_Node T){
stack<P_Node> Stack;
P_Node pCur; //定义指针，指向当前节点
P_Node pPre = NULL;//定义指针，指向上一各访问的节点

Stack.push(T);
while(!Stack.empty()){
pCur = Stack.top();
//如果当前节点没有左右孩子，或者有左孩子或有孩子，但已经被访问输出，
//则直接输出该节点，将其出栈，将其设为上一个访问的节点
if((pCur->lchild==NULL && pCur->rchild == NULL) ||
(pPre != NULL && (pCur->lchild==pPre || pCur->rchild == pPre))){
printf("%3c",pCur->data);
Stack.pop();
pPre = pCur;
}else{
//如果不满足上面两种情况,则将其右孩子左孩子依次入栈
if(pCur->rchild != NULL)
Stack.push(pCur->rchild);
if(pCur->lchild != NULL)
Stack.push(pCur->lchild);
}
}
}

int main(){
P_Node T;
createTree(T);
printf("\n非递归前序遍历：");
preOrderTraversal(T);
printf("\n非递归中序遍历：");
midOrderTraversal(T);
printf("\n非递归后续遍历：");
afterOrderTraversal(T);
printf("\n");
printf("Hello world !\n");
return 0;
}