希尔排序
优化版的插入排序,优化的地方就是步长(增量)增大了,原来的插入排序的步长(增量)是1,而希尔排序的步长(增量)可以很大,然后逐渐减小直到1形成插入排序 也叫(减小增量排序) 若不了解,可看之前发布的希尔排序 void shellSort1(int arr[],int length){ for(int i=interval;i<arr.length;i+=interval){ int target=arr[i]; int j=i-interval; while(target<arr[j]){ arr[j+inertval]=arr[j]; j-=interval; } arr[j+interval]=target; } } 个人感觉shellSort2更复杂一些。 void shellSort2(int arr[],int length){ int h=4; while(h>=1){ for(int i=h;i<length;i++){ for(int j=i;j>=h&&arr[j]<arr[j-h];j-=h){ int temp=arr[j]; arr[j]=arr[j-h]; arr[j-h]=temp; } } h/=2; } }
shellSort1的增量为length/2,不断取半 个人感觉shellSort1更好用,shellSort2复杂一些,shellSort更复杂。 经典的希尔序列1,4,13,.....,3*n+1 void shellSort3(int arr[],int length){ int h=1; int t=length/3; while(h<t) h=3*h+1;//让步长(增量)在length左右 //shellSort2的步长给锁死成4了,不过挺好用 while(h>=1){ for(int i=h;i<length;i++){ for(int j=i;j>=h&&arr[j]<arr[j-h];j-=h){ int temp=arr[j]; arr[j]=arr[j-h]; arr[j-h]=temp; } } h/=3; } }
快速排序
冒泡排序的优化版本,核心思想:使用轴,每一轮左右递归后,把轴放到中间,使得轴的左边都比轴小,轴的右边东渡比轴大,当所有的递归都结束了就自然排序好了 pivot:轴(主元)一般选第一个元素 需要用到双指针,一个左指针,一个右指针 左指针找比轴(主元)大的,右指针找比轴(主元)小的 然后二者值交换 void quickSort(int arr[],int left,int right){ if(left>=right) return; int i=left;//左指针 int j=right;//右指针 int pivot=arr[i];//该整体第一个元素,并将主元提取出来 while(i<j){ while(i<j&&arr[j]>=pivot)j--;//找右边第一个小于pivot的值 arr[i]=arr[j];//然后把小于pivot的值给主元所在位置 while(i<j&&arr[i]<=pivot)i++;//找左边第一个大于pivot的值 arr[j]=arr[i];将该值赋给第一个小于pivot的值 //保留一个空位,即原来主元空出来的位置,可用于值的交换 //左指针每找到一个大于pivot的值,就停下,右指针每找到一个小于pivot的值,就停下,然后二者互换 // while(i<j&&arr[i]<=pivot)循环条件添加i<j是因为,在while(i<j)这个大循环中,仍有两个while嵌套,第一个while结束后,第二个while会继续执行,i和j的位置就彼此越界了 } arr[i]=pivot; quickSort(arr,left,i-1); quickSort(arr,i+1,right); } (第二种写法) void swap(int arr[],int i,int j){//换值函数 int temp=arr[i]; arr[i]=arr[j]; arr[j]=temp; } void quickSort2(int arr[],int left[],int right){//另一种快速排序的样例 if(left>=right) return; int pivot=arr[left]; int i=left+1;//这里有两个指针 int j=left+1; while(j<=right){ //每轮循环,j都向右移一位 if(arr[j]<pivot){//如果j指向的值小于pivot swap(arr,i,j);//则交换i和j的值 i++; //每次将小于pivot的值移到左边,i右移一位,i就用于等待交换的位置,每次j找到小于pivot的值,都与i位置上的数交换 } j++;//j用于寻找小于pivot的值 } swap(arr,left,i-1);//while循环结束后,i最后+1了,所以i-1为最后一个小于pivot的值的位置,因此将主元left上的值与i-1的值交换 quickSort2(arr,left,i-2);//主元左边 quickSort2(arr,i,right);//主元右边 }