冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,我想你是不会再无聊地把他们俩交换一下的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。

冒泡排序算法的运作如下:
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较

void  maopao(int *arr,int n)
{
	int j,i;
	int temp;
	for(j=n-1;j>0;j--)
	{
	   for(i=0;i<=j;i++)
		{
		  if(arr[i]>arr[i+1])
		  {
			temp=arr[i];
			arr[i]=arr[i+1];
			arr[i+1]=temp;
		  }
		}
	}
	 printf("冒泡排序:");
	 for(int k=0;k<n;k++)
    {
    	printf("%d ",arr[k]);
    }
    
}
void maopao2(int *puke,int count)
{


	int temp;
	int i;
	for(int j=count-1;j>0;j--)
	{
		for(i=0;i<j;i++)	///4----1
		{
			if(puke[i]>puke[i+1])	//0----3     1----4
			{
				temp=puke[i+1];	//1----4
				puke[i+1]=puke[i];//1----4	0----3
				puke[i]=temp;	//0---3
			}
		}
	}
   printf("冒泡排序二:");
     for(i=0;i<count;i++)
    {
    	printf("%d ",puke[i]);
    }
   
	return;
}


选择排序:


n个记录的文件的直接选择排序可经过n-1趟直接选择排序得到有序结果:


①初始状态:无序区为R[1..n],有序区为空。



第1趟排序


在无序区R[1..n]中选出关键字最小的记录R[k],将它与无序区的第1个记录R[1]交换,使R[1..1]和R[2..n]分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区。


……


③第i趟排序


第i趟排序开始时,当前有序区和无序区分别为R[1..i-1]和R(i..n)。该趟排序从当前无序区中选出关键字最小的记录 R[k],将它与无序区的第1个记录R交换,使R[1..i]和R分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区。


常见的选择排序细分为简单选择排序、树形选择排序(锦标赛排序)、堆排序。上述算法仅是简单选择排序的步骤。


void selete(int *arr,int n)
{
	int s;
	int temp;
    int i,j;
 
  for(j=0;j<n-1;j++)
   {
   	  s=j;
     for(i=1+j;i<n;i++)	
	 {
	  if(arr[s]>arr[i])
	   {
	    	s=i; 
	   }
       temp=arr[s];
       arr[s]=arr[i];
       arr[i]=temp; 
     }


 
 }
 
    printf("选择排序:");
    for(int i=0;i<n;i++)
    {
    	printf("%d ",arr[i]);
    }
   
}


插入排序:


将n个元素的数列分为已有序和无序两个部分,如


插入排序过程示例


  插入排序过程示例


下所示:


{{a1},{a2,a3,a4,…,an}}


{{a1⑴,a2⑴},{a3⑴,a4⑴ …,an⑴}}




{{a1(n-1),a2(n-1) ,…},{an(n-1)}}


每次处理就是将无序数列的第一个元素与有序数列的元素从后往前逐个进行比较,找出插入位置,将该元素插入到有序数列的合适位置中。


void insert_sort(int *arr,int n)
{
	int m=sizeof(n)/sizeof(int);
	int i,j;
	int temp;
	int min;


    for(i=2;i<n;i++)
    {
    	  j=i-1;	
  	      while(arr[0]<arr[j])
    	  {
		     arr[j+1]=arr[j];
    	     j--;
    	     arr[0]=arr[j];
		  }
    }


    printf("插入排序:");
    for(int k=0;k<n;k++)
    {
	   printf("%d",arr[k]);
    }
}


void insertSort2(int *arr,int n)
{
	int i,j;
	int temp;
	
	for(i=0;i<n;i++)
    {
   	   for(j=i;j>=0;j--)
        {
        	if(arr[j]>arr[j+1])
  			{
			  temp=arr[j];
  			  arr[j]=arr[j+1];
  			  arr[j+1]=temp;
  			}
  			
  		}	
   	}
   	printf("插入排序二:");
   for(int k=0;k<n;k++)
    {
	   printf("%d",arr[k]);
    }
	
}



二分查找法:

折半查找法也称为二分查找法,它充分利用了元素间的次序关系,采用分治策略,可在最坏的情况下用O(log n)完成搜索任务。它的基本思想是,将n个元素分成个数大致相同的两半,取a[n/2]与欲查找的x作比较,如果x=a[n/2]则找到x,算法终止。如 果x<a[n/2],则我们只要在数组a的左半部继续搜索x(这里假设数组元素呈升序排列)。如果x>a[n/2],则我们只要在数组a的右 半部继续搜索x。

二分查找法一般都存在一个临界值的BUG,即查找不到最后一个或第一个值。可以在比较到最后两个数时,再次判断到底是哪个值和查找的值相等。


int  find_binary(int *arr,int n,int num)
{
    int mid,low,high;
	low=0;
	high=n-1;
	int position=0;
	
	if(n<1)
	{
		return -1;
	}


	mid=(low+high)/2;
	if(num==arr[mid])
	{
		position=mid;
	}
	
	else if(num<arr[mid])
	{
		position=find_binary(arr+low,mid,num);
	}
	
	else if(num>arr[mid]) 
	{
	    int temp=find_binary(arr+mid+low,n-mid-1,num);
        if(temp!=-1)position=temp+mid+1;
	}


   return position;
}



全部程序源码:

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


void  maopao(int *arr,int n)
{
	int j,i;
	int temp;
	for(j=n-1;j>0;j--)
	{
	   for(i=0;i<=j;i++)
		{
		  if(arr[i]>arr[i+1])
		  {
			temp=arr[i];
			arr[i]=arr[i+1];
			arr[i+1]=temp;
		  }
		}
	}
	 printf("冒泡排序:");
	 for(int k=0;k<n;k++)
    {
    	printf("%d ",arr[k]);
    }
    
}
void maopao2(int *puke,int count)
{


	int temp;
	int i;
	for(int j=count-1;j>0;j--)
	{
		for(i=0;i<j;i++)	///4----1
		{
			if(puke[i]>puke[i+1])	//0----3     1----4
			{
				temp=puke[i+1];	//1----4
				puke[i+1]=puke[i];//1----4	0----3
				puke[i]=temp;	//0---3
			}
		}
	}
   printf("冒泡排序二:");
     for(i=0;i<count;i++)
    {
    	printf("%d ",puke[i]);
    }
   
	return;
}


void selete(int *arr,int n)
{
	int s;
	int temp;
    int i,j;
 
  for(j=0;j<n-1;j++)
   {
   	  s=j;
     for(i=1+j;i<n;i++)	
	 {
	  if(arr[s]>arr[i])
	   {
	    	s=i; 
	   }
       temp=arr[s];
       arr[s]=arr[i];
       arr[i]=temp; 
     }


 
 }
 
    printf("选择排序:");
    for(int i=0;i<n;i++)
    {
    	printf("%d ",arr[i]);
    }
   
}


void insert_sort(int *arr,int n)
{
	int m=sizeof(n)/sizeof(int);
	int i,j;
	int temp;
	int min;


    for(i=2;i<n;i++)
    {
    	  j=i-1;	
  	      while(arr[0]<arr[j])
    	  {
		     arr[j+1]=arr[j];
    	     j--;
    	     arr[0]=arr[j];
		  }
    }


    printf("插入排序:");
    for(int k=0;k<n;k++)
    {
	   printf("%d",arr[k]);
    }
}


void insertSort2(int *arr,int n)
{
	int i,j;
	int temp;
	
	for(i=0;i<n;i++)
    {
   	   for(j=i;j>=0;j--)
        {
        	if(arr[j]>arr[j+1])
  			{
			  temp=arr[j];
  			  arr[j]=arr[j+1];
  			  arr[j+1]=temp;
  			}
  			
  		}	
   	}
   	printf("插入排序二:");
   for(int k=0;k<n;k++)
    {
	   printf("%d",arr[k]);
    }
	
}


int  find_binary(int *arr,int n,int num)
{
    int mid,low,high;
	low=0;
	high=n-1;
	int position=0;
	
	if(n<1)
	{
		return -1;
	}


	mid=(low+high)/2;
	if(num==arr[mid])
	{
		position=mid;
	}
	
	else if(num<arr[mid])
	{
		position=find_binary(arr+low,mid,num);
	}
	
	else if(num>arr[mid]) 
	{
	    int temp=find_binary(arr+mid+low,n-mid-1,num);
        if(temp!=-1)position=temp+mid+1;
	}


   return position;
}


int main()
{
	int arr[]={0,2,4,6,7,10};
	int arr2[]={5,7,2,3,1};
	//int n=6;//(malloc(strlen(arr)+1)/sizeof(int));	
	int m=sizeof(arr)/sizeof(int);
	int n=sizeof(arr2)/sizeof(int);
	
	printf("排序数字个数:%d\n",n);
	printf("查找数字个数:%d\n",m);
	
	maopao(arr,n);//冒泡排序 
	printf("\n");
	
	maopao2(arr,n);//冒泡排序 2
	printf("\n");
	
	selete(arr,n);//选择排序 
	printf("\n");
	
	insert_sort(arr,n);//插入排序 
	printf("\n");
    
    insertSort2(arr,n);//插入排序第二种方法 
    printf("\n");
    
    int position=find_binary(arr,m,4);//二份查找 
    printf("位置是:%d\n",position);
    printf("\n");
    
	return 0;
}



运行结果:

数据结构之排序和查找_数据结构