zoukankan      html  css  js  c++  java
  • 排序

    绪论

    身为程序员,十大排序是对每一个程序员都应该掌握的算法,现在比较流行的算法如快速排序、归并排序等,对算法的时间复杂度和空间复杂度的掌握都有要求。本文将分享常见的十大排序算法,基于Java和C语言实现,让你能够掌握!

    对于排序的分类,可以根据不同的角度比如时间、空间复杂度、比较非比较等角度来划分。我们通常的十大排序都是内部排序,通常的话,基于[比较和非比较]这个层次来划分:

    (1)交换类

    [1]冒泡排序

    基本思想:循环遍历多次,每次从前往后把大元素往后调,每次确定一个最大(最小)元素,多次到达排序序列。
    实现代码:(Java)

    
    public void  maopaosort(int[] a) {
    		  for(int i=a.length-1;i>=0;i--)
    		  {
    		    for(int j=0;j<i;j++)
    		    {
    		      if(a[j]>a[j+1])
    		      {
    		        int team=a[j];
    		        a[j]=a[j+1];
    		        a[j+1]=team;
    		      }
    		    }
    		  }
    		}
    

    实现代码:(C语言)

    
    void bubble_sort(int a[], int n)     
    {
        int i,j,temp;     
        for (j=0;j<n-1;j++)      
        {                           
            for (i=0;i<n-1-j;i++)
            {
                if(a[i]>a[i+1])  
                {
                    temp=a[i];      
                    a[i]=a[i+1];    
                    a[i+1]=temp;
                }
            }
        }    
    }
    

    [2]快速排序

    基本思想:将一个序列分为2部分,序列左边全部小于一个数,序列右边全部大于一个数。然后利用递归的思想再将左序列当成一个完整的序列再进行排序,同样把序列的右侧也当成一个完整的序列进行排序。
    实现代码:(Java)

    
    public void quicksort(int [] a,int left,int right)
    	{
    	  int low=left;
    	  int high=right;
    	  if(low>high)
    	    return;
    	  int k=a[low];
    	  while(low<high)
    	  {
    	    while(low<high&&a[high]>=k)
    	    {
    	    	high--;
    	    }
    	    a[low]=a[high];
    	    while(low<high&&a[low]<=k)
    	    {
    	    	low++;
    	    }
    	    a[high]=a[low];   
    	  }
    	  a[low]=k;
    	  quicksort(a, left, low-1);
    	  quicksort(a, low+1, right);  
    	}
    

    实现代码:(C语言)

    
    void QuickSort(int* data, int left, int right, int direction)
    {
    	int i = left, j = right, index = data[left];
    	if (data == NULL)
    		return;
    	if (right >= sizeof(*data)/sizeof(int))return;
    	if (left < 0)
    		return;
    
    	if (left >= right)
    		return;
    	while(i<j)
    	{
    		while(data[j]<=index)
    			j--;
    		data[i] = data[j];
    		while(data[i]>=index&&i < j)
    			i++;
    		data[j]=data[i];
    	}
    	data[i]=index;
    	QuickSort(data,left,i-1,direction);
    	QuickSort(data,i+1,right,direction);
    }
    

    (2)插入类

    [3]直接插入排序

    基本思想:简单的说,就是按身高来排序,从第一个开始,如果前面有比自己高的,就直接插入到合适的位置。一直到队伍的最后一个完成插入,整个队列才能满足有序。
    实现代码:(Java)

    
    public void insertsort (int a[])
    	{
    		int team=0;
    		for(int i=1;i<a.length;i++)
    		{
    			System.out.println(Arrays.toString(a));
    			team=a[i];
    			for(int j=i-1;j>=0;j--)
    			{
    				if(a[j]>team)
    				{
    					a[j+1]=a[j];
    					a[j]=team; 
    				} 
    				else {
    					break;
    				}
    			}
    		} 
    	}
    

    实现代码:(C语言)

    
    void insertsort(int *k,int n)            
    {
        int i,j;
        int temp;
        for(i=1;i<n;i++)
        {
            temp = k[i];               
            j = i - 1;
            while(j>=0 && k[j]>temp)    
            {
                k[j+1] = k[j];           
                j--;
            }
            k[j+1] = temp;                 
        }
    }
    

    [4]希尔排序

    基本思想:希尔排序是特殊的插入排序,直接插入排序每次插入前的遍历步长为1,而希尔排序是将待排序列分为若干个子序列,对这些子序列分别进行直接插入排序,当每个子序列长度为1时,再进行一次直接插入排序时,结果一定是有序的。常见的划分子序列的方法有:初始步长(两个子序列相应元素相差的距离)为要排的数的一半,之后每执行一次步长折半。
    实现代码:(Java)

    
    public void shellsort (int a[])
    	{
    		int d=a.length;
    		int team=0;
    		for(;d>=1;d/=2)
    			for(int i=d;i<a.length;i++)
    	    	{
    				team=a[i];
    				for(int j=i-d;j>=0;j-=d)
    				{    
    					if(a[j]>team)
    					{
    						a[j+d]=a[j];
    						a[j]=team; 
    					}
    					else {
    						break;
    					}
    				}
    	    	} 
    	}
    

    实现代码:(C语言)

    
    void shellSort(int *a, int len)
    {
        int i, j, k, tmp, gap;  
        for(gap=len/2;gap>0;gap/=2) {  
        	for(i=0;i<gap;++i) { 
    	        for(j=i+gap;j<len;j+=gap) { 
    	            tmp=a[j];  
    	            k=j-gap;  
    	            while(k>=0&&a[k]>tmp) {
    	                a[k+gap]=a[k]; 
    	                k-=gap;
    	            }
    	            a[k+gap]=tmp; 
    	        }
    	    }
        }
    }
    

    (3)选择类

    [5]简单选择排序

    基本思想:首先,选出最小的数,放在第一个位置;然后,选出第二小的数,放在第二个位置;以此类推,直到所有的数从小到大排序。
    实现代码:(Java)

    
    public void selectSort(int[] arr) {
    		  for(int i = 0; i < arr.length-1;i++) {
    		    int min = i; 
    		    for(int j = i + 1; j < arr.length;j++) {
    		      if(arr[j]<arr[min]) {
    		        min=j; 
    		      }
    		    }
    		    if(min!=i) {
    		      swap(arr,i,min); 
    		    }
    		  }
    		}
    		public void swap(int[] arr, int i, int j) {
    		  int temp=arr[i];
    		  arr[i]=arr[j];
    		  arr[j]=temp;
    		}
    

    实现代码:(C语言)

    
    void SelectSort(int a[],int n){ 
        int mix,temp;
        int i,j;
        for(i=0;i<n-1;i++){ 
            mix=i; 
            for(j=i+1;j<n;j++)
                if(a[j]<a[mix])
                    mix=j;
            if(i!=mix) {
                temp=a[i];
                a[i]=a[mix];
                a[mix]=temp;
            }
        }
    }
    

    [6]堆排序

    基本思想:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。
    实现代码:(Java)

    
    static void swap(int arr[],int m,int n)
    		{
    		  int team=arr[m];
    		  arr[m]=arr[n];
    		  arr[n]=team;
    		}
    		static void shiftDown(int arr[],int index,int len)
    		{
    		  int leftchild=index*2+1;
    		  int rightchild=index*2+2;
    		  if(leftchild>=len)
    		    return;
    		  else if(rightchild<len&&arr[rightchild]<arr[index]&&arr[rightchild]<arr[leftchild])
    		  {
    		    swap(arr, index, rightchild);
    		    shiftDown(arr, rightchild, len);
    		  }
    		  else if(arr[leftchild]<arr[index])
    		  {
    		    swap(arr, index, leftchild);
    		    shiftDown(arr, leftchild, len);
    		  }
    		}
    		static void creatHeap(int arr[])
    		{
    		  for(int i=arr.length/2;i>=0;i--)
    		  {
    		    shiftDown(arr, i,arr.length);
    		  }
    		}
    		static void heapSort(int arr[])
    		{
    		  System.out.println("原始数组为         :"+Arrays.toString(arr));
    		  int val[]=new int[arr.length]; 
    		  creatHeap(arr);
    		  System.out.println("建堆后的序列为  :"+Arrays.toString(arr));
    		  for(int i=0;i<arr.length;i++)
    		  {
    		    val[i]=arr[0];
    		    arr[0]=arr[arr.length-1-i];
    		    shiftDown(arr, 0, arr.length-i);
    		  }
    		  for(int i=0;i<arr.length;i++)
    		  {
    		    arr[i]=val[i];
    		  }
    		  System.out.println("堆排序后的序列为:"+Arrays.toString(arr));
    		}
    

    实现代码:(C语言)

    
    void AdjustDown(DataType* a, size_t n, int parent)
    {
        int child = parent * 2 + 1;
        while(child < n)
        {
            if((child + 1 < n)&&(a[child+1]>a[child]))
            {
                ++child;
            }
            if(a[child]>a[parent])
            {
                Swap(&a[child], &a[parent]);
                parent=child;
                child = parent * 2 + 1;
            }
            else
            {
                break;
            }
        }
    }
    void HeapSort(DataType* a, size_t n)
    {
        assert(a);
        for(int i = (n - 2) / 2; i >= 0; i--)
        {                       
            AdjustDown(a, n, i);
        }
        int end = n - 1;
        while(end > 0)
        {
            Swap(&a[0], &a[end]);
            AdjustDown(a, end, 0);
            --end;
        }
    }
    

    (4)归并类

    [7]归并排序

    基本思想:将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并, 使用中牺牲空间换取时间的算法。
    实现代码:(Java)

    
    private static void mergesort(int[] array, int left, int right) {
    			  int mid=(left+right)/2;
    			  if(left<right)
    			  {
    			    mergesort(array, left, mid);
    			    mergesort(array, mid+1, right);
    			    merge(array, left,mid, right);
    			  }
    			}
    			private static void merge(int[] array, int l, int mid, int r) {
    			  int lindex=l;int rindex=mid+1;
    			  int team[]=new int[r-l+1];
    			  int teamindex=0;
    			  while (lindex<=mid&&rindex<=r) {
    			    if(array[lindex]<=array[rindex])
    			    {
    			    	team[teamindex++]=array[lindex++];
    			    }
    			    else {    
    			    	team[teamindex++]=array[rindex++];
    			    }
    			  }
    			  while(lindex<=mid)
    			  {
    				  team[teamindex++]=array[lindex++];
    			  }
    			  while(rindex<=r)
    			  {
    				  team[teamindex++]=array[rindex++];
    			  } 
    			  for(int i=0;i<teamindex;i++)
    			  {
    				  array[l+i]=team[i];
    			  }
    			}
    

    实现代码:(C语言)

    
    void merge(int arr[], int start, int mid, int end) {
    	int result[ArrLen];
    	int k = 0;
    	int i = start;
    	int j = mid + 1;
    	while (i <= mid && j <= end) {
    		if (arr[i] < arr[j]){
    			result[k++] = arr[i++];
            }
    		else{
    			result[k++] = arr[j++];
            }
    	}
    	if (i == mid + 1) {
    		while(j <= end)
    			result[k++] = arr[j++];
    	}
    	if (j == end + 1) {
    		while (i <= mid)
    			result[k++] = arr[i++];
    	}
    	for (j = 0, i = start ; j < k; i++, j++) {
    		arr[i] = result[j];
    	}
    }
    void mergeSort(int arr[], int start, int end) {
    	if (start >= end)
    		return;
    	int mid = ( start + end ) / 2;
    	mergeSort(arr, start, mid);
    	mergeSort(arr, mid + 1, end);
    	merge(arr, start, mid, end);
    }
    

    (5)桶类排序

    [8]桶排序

    基本思想:把数组中的所有元素分为若干个数据块,也就是若干个桶,然后对每个桶里的数据进行排序,最后将所有桶里的数据依次排列即可。
    实现代码:(Java)

    
    public class bucketSort {
    				 public static void main(String[] args) {
    				  int a[]= {1,8,7,44,42,46,38,34,33,17,15,16,27,28,24};
    				  List[] buckets=new ArrayList[5];
    				  for(int i=0;i<buckets.length;i++)
    				  {
    					  buckets[i]=new ArrayList<Integer>();
    				  }
    				  for(int i=0;i<a.length;i++)
    				  {
    					  int index=a[i]/10;
    					  buckets[index].add(a[i]);
    				  }
    				  for(int i=0;i<buckets.length;i++)
    				  {
    					  buckets[i].sort(null);
    				   for(int j=0;j<buckets[i].size();j++)
    				   {
    					   System.out.print(buckets[i].get(j)+" ");
    				   }
    				  } 
    				 }
    				}
    

    实现代码:(C语言)

    
    typedef struct node {
    	int key;
    	struct node *next;
    }KeyNode;
    void bucket_sort(int keys[],int size,int bucket_size) {
    	int i,j;
    	KeyNode **bucket_table = (KeyNode **)malloc(bucket_size * sizeof(KeyNode*));
    	for(i = 0;i < bucket_size;i++) {
    		bucket_table[i] = (KeyNode*)malloc(sizeof(KeyNode));
    		bucket_table[i]->key = 0;
    		bucket_table[i]->next = NULL;
    	}
    	for(j = 0;j < size;j++) {
    		KeyNode *node = (KeyNode *)malloc(sizeof(KeyNode));
    		node->key = keys[j];
    		node->next = NULL;
    		int index = keys[j]/10;
    		KeyNode *p = bucket_table[index];
    		if(p->key == 0) {
    			bucket_table[index]->next = node;
    			(bucket_table[index]->key)++;
    		}else {
    			while(p->next != NULL && p->next->key <= node->key)
    				p = p->next;
    			node->next = p->next;
    			p->next = node;
    			(bucket_table[index]->key)++;
    		}
    	}
    	KeyNode * k = NULL;
    	for(i = 0;i < bucket_size;i++)
    		for(k = bucket_table[i]->next;k!=NULL;k=k->next)
    			printf("%d ",k->key);
    	printf("
    ");
    }
    

    [9]计数排序

    基本思想:先找到最小值min,再找最大值max。然后创建这个区间大小的数组,从min的位置开始计数,这样就可以最大程度地压缩空间,提高空间的使用效率。
    实现代码:(Java)

    
    public static void countSort(int a[])
    			{
    				int min=Integer.MAX_VALUE;int max=Integer.MIN_VALUE;
    				for(int i=0;i<a.length;i++)
    				{
    					if(a[i]<min) 
    						min=a[i];
    					if(a[i]>max)
    						max=a[i];
    				}
    				int count[]=new int[max-min+1];
    				for(int i=0;i<a.length;i++)
    				{
    					count[a[i]-min]++;
    				}
    				int index=0;
    				for(int i=0;i<count.length;i++)
    				{
    					while (count[i]-->0) {
    						a[index++]=i+min;
    					}
    				}
    			}
    

    [10]基数排序

    基本思想:将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。在每一次排序中,按照当前位把数组元素放到对应的桶当中,然后把桶0到桶9中的元素按先进先出的方式放回数组中。这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。
    实现代码:(Java)

    
    static void radixSort(int[] arr)
    			{
    				List<Integer>bucket[]=new ArrayList[10];
    				for(int i=0;i<10;i++)
    				{
    					bucket[i]=new ArrayList<Integer>();
    				}
    				int max=0;
    				for(int i=0;i<arr.length;i++)
    				{
    					if(arr[i]>max)
    						max=arr[i];
    				}
    				int divideNum=1;
    				while (max>0) {
    					for(int num:arr)
    					{
    						bucket[(num/divideNum)%10].add(num);
    					}
    					divideNum*=10;
    					max/=10;
    					int idx=0;
    					for(List<Integer>list:bucket)
    					{
    						for(int num:list)
    						{
    							arr[idx++]=num;
    						}
    						list.clear();
    					}
    				}
    			}
    

    结语

    十大排序算法就分享给大家了!下面是对算法的总结:

  • 相关阅读:
    hello , world Tkinter代码描述
    Tkinter 类
    什么是Tkinter?
    99_恢复二叉搜索树
    总结eclipse中常用好用的快捷键或者自定义一下快捷键:
    封装与职责分离的开发思维
    正在学习的路上
    串比较
    坚持的力量 第二十篇
    串连接
  • 原文地址:https://www.cnblogs.com/hunanloudi/p/14932348.html
Copyright © 2011-2022 走看看