ios算法总结(非完整版)

#include <stdio.h>

//.选择排序

//.冒泡排序

//.直接插入排序

//.希尔排序

//.快速排序

//.堆排序

快速排序:从数列中挑出一个元素,称为 "基准"(pivot),重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

归并排序:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;

设定两个指针,最初位置分别为两个已经排序序列的起始位置;

比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;

重复步骤3直到某一指针达到序列尾;

将另一序列剩下的所有元素直接复制到合并序列尾。

堆排序:堆积排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

选择排序:选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下。首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,然后放到排序序列末尾。以此类推,直到所有元素均排序完毕。

冒泡排序:比较相邻的元素。如果第一个比第二个大,就交换他们两个。

对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。

针对所有的元素重复以上的步骤,除了最后一个。

持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

插入排序:从第一个元素开始,该元素可以认为已经被排序;

取出下一个元素,在已经排序的元素序列中从后向前扫描;

如果该元素(已排序)大于新元素,将该元素移到下一位置;

重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;

将新元素插入到该位置中,重复步骤2

希尔排序:也称递减增量排序算法,是插入排序的一种高速而稳定的改进版本。

希尔排序是基于插入排序的以下两点性质而提出改进方法的:

插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率;

但插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位。


void inputArray(int arr[],int *nums){

    printf("please input the number of array:");

   scanf("%d",nums);

    printf("please input %d numbers:",*nums);

   int i = 0 ;

   for (; i<*nums; i++) {

       scanf("%d",&arr[i]);

    }

}

void printArray(int arr[],int nums){

   int i = 0 ;

   for (; i<nums; i++) {

       if (i==nums-1) {

           printf("%d\n",arr[i]);

        }else{

           printf("%d ->",arr[i]);

        }

        

    }

}

void swap(int *a,int *b){

   int temp  = *a;

    *a = *b;

    *b = temp;

}

//.选择排序从小到大排序

/*

 算法思路:i , j ; n为数组长度

 i0遍历到n-2:

 对于每个i,j每次从i+1遍历到n-1,选出[i,n-1]最小的元素下标minIndex,然后把该次遍历的最小元素arr[minIndex]arr[i]交换.

 i遍历完n-2时就确定了整个数组的有序.

 算法复杂度:O(n*n)

 */

void select_sort(int arr[],int nums){

   int i,j;

   for (i=0; i<nums-1; i++) {

       int minIndex = i;

       for (j=i+1; j<nums; j++) {

           if (arr[i]>arr[j]) {

                minIndex = j;

            }

        }

       if (minIndex!=i) {

           swap(&arr[i], &arr[minIndex]);

        }

    }

}

//.冒泡排序从小到大排序

/*

 算法思路:

 i0n-2,对于每个i:jn-1i+1(递减1),对于每个j,都要比较arr[j]arr[j-1],如果arr[j]小于

 arr[j-1]则交换两数,确保每个arr[j-1]大于arr[j].

 这样对于每个i,j遍历完后,arr[i]jn-1遍历到i+1"冒泡"上来的最小值,这样i遍历完后,就确定了整个数组的有序了.

 算法复杂度为:O(n*n)

 */

void bubble_sort(int arr[],int n){

   int i =0 ,j =0 ;

   for (; i<n-1; i++) {

       for (j=n-1; j>i; j--) {

           if (arr[j]<arr[j-1]) {

               swap(&arr[j], &arr[j-1]);

            }

        }

    }

}

//.直接插入排序从小到大排序

/*

 算法思路:

 i0n-2,对于每个i:   ji+1递减到1,对于每个j:判断arr[j]arr[j-1]如果arr[j]<arr[j-1],则交换两数,否则跳出内循环.

 上面的整体思路是:每次把arr[j=i+1]的元素,插入到前面有序的子数组(arr[0],...,arr[i]),

 i=0,子数组为(arr[0]).

 

 算法复杂度为:O(n*n)

 */

void insert_sort(int arr[],int n){

   int i =0 , j =0 ;

   for (i=0; i<n-1; i++) {

       for (j=i+1; j>0; j--) {

           if (arr[j-1]<arr[j]) {

               break;

            }

           swap(&arr[j-1], &arr[j]);

        }

    }

}

//.希尔排序从小到大排序

/* 希尔排序算法 也称缩小增量排序算法 是一种特殊的插入排序

 这里需要假设一个增量dk,

 我这里的dk一开始dk=3,然后每次循环递减1,dk--:

 对于每个增量长度dk,:原数组的子数组(0,0+dk,0+2*dk,.....,0+i*dk),然后对该子数组进行直接插入排序.

 这里的dk的值可以按情况设置.

 我这里的是dk=3,dk=2,dk=1.

 

 总结希尔排序的算法复杂度有点麻烦,取于dk(dlta[k])的值和数组.

 有人指出,dlta[k] = 2^(t-k+1)-1,希尔排序的时间复杂度为:O(n^(3/2)),其中t为排序躺数. 1<=k<=t<=向下取整[log2 (n+1)]

 还有人经过大量实验,,n在特定范围内,希尔排序所需的比较和移动次数约为n^(1.3),n->∞,可减少到n*(log2(n))^2*[2].

 */

void shell_sort(int arr[],int n){

   int dk = 3 ;

   int i = 0 ,j=0;

   for (dk = 3; dk>0; dk--) {

        //对于每个增量dk,对子数组进行直接排序

       for (i=0; i+dk<n; i+=dk) {

           for (j=i+dk; j-dk>=0; j-=dk) {

               if (arr[j]<arr[j-dk]) {

                   swap(&arr[j], &arr[j-dk]);

                }else{

                   break;

                }

            }

        }

    }

}

//.快速排序从小到大排序

/*

 快速排序是对冒泡排序的一种改进,基本思想是通过一趟排序将待排序记录分割成独立的两部分,其中左边的value比右边的value,则然后再分别对这两部分递归处理,从而继续进行排序,以达到整个序列有序.

 每一趟都要选取一个枢轴pivotkey(这里选取pivotkey = arr[low]),遍历该当前部分的元素,默认把比pivotkey小的放在左边,pivotkey大的放在右边,然后得到两个子数组,对该子数组再进行相同操作.这里设置了一个lowhigh,(low,high)作为该当前数组的第一个元素位置和最后一个元素位置,具体做法是:首先从high所指位置起向前搜索,找到第一个关键值比当前pivotkey小的元素,与枢轴记录互相交换,然后从low所指的位置起向后搜索,找到第一个关键值比pivotkey的元素,和枢轴记录相互交换,重复这两步直至low = high为止.

 算法时间复杂度为O(n*log2(n));

 */

int partition(int arr[],int low,int high){

   if (low>=high) {

       return low;

    }

   int pivotkey = arr[low];

   while (low<high) {

       while (low<high&&arr[high]>=pivotkey)high--;

        arr[low] = arr[high];

       while (low<high&&arr[low]<=pivotkey)low++;

        arr[high] = arr[low];

    }

    arr[low] = pivotkey ;

   return low ;

}

void quick_sort(int arr[],int low,int high){

   if (low>=high) {

       return;

    }

   int pivot = partition(arr, low, high);

   quick_sort(arr, low, pivot-1);

   quick_sort(arr, pivot+1, high);

    

}



//.堆排序从大到小排序

/*

 堆排序(Heap_Sort),这里用到一个特别的数据结构--.具体结构可以参考数据结构相关书籍的定义.

 堆的定义如下:n个元素的序列{a[0],a[1],...,a[n-1]}当且仅当满足下关系时,称为堆.

 1). a[i] <= a[2*i+1] a[i] <= a[2*i+2] (称为最小堆)

 或者满足:2). a[i] <= a[2*i+1] a[i] <= a[2*i+2] (称为最大堆)

 其中, i=1,2,3,...,[n/2]向下取整

 这里的序列可以将一个一维数组相对应进行存储.

 

 堆的逻辑结构其实就是一个完全二叉树.第一个结点a[0]就是堆的根结点(就是堆顶),若是最小堆,a[0]是最小堆的最小值的元素,若是最大堆,a[0]是最大堆中的最大值元素.

 对于a[i]结点,它的左结点是a[2*i+1],右结点是a[2*i+2].

 对于某一结点a[k](除了根节点a[0],k!=0),其父节点是a[(k-1)/2].

 

 堆的基本函数有:

 1). 堆的创建(自下往上)

 2). 堆调整(自上往下调整)

 3). 取堆顶:访问堆的根节点,并删除该结点,其结点由堆最后的结点补上(堆顶与堆最后一个元素交换),并进行堆调整.

 *4). 堆排序

 

 这里需要了解过堆的逻辑结构才能比较容易看懂函数代码,请先查阅相关数据结构的书籍再研究以下算法.

 */

/*

 以下是创建最小堆的例子,最小堆得到的堆排序是从大到小的,最大堆得到的堆排序是从小到大的.最大堆可以由读者来实现.

 */

void Heap_create(int heap[],int nums);

void heap_adjust(int heap[],int pos,int nums);

void printHeap(int heap[],int n);

void heap_sort(int heap[],int nums);

/*

 // 1)堆的创建(自下往上)

 步骤: 1) 假设待调整数组为heap[],其元素个数为nums,则从最后一个元素的父节点开始遍历调整,即从heap[(nums-1-1)/2]开始自上往下调整子堆.

 */

void Heap_create(int heap[],int nums){

   if(nums<1){

        //堆中没元素,不需要调整

       return ;

    }

   int i = (nums-1-1)/2;//获取最后一个元素的父节点

   for (; i>=0; i--) {

        //开始遍历结点,然后对该结点进行自上往下调整

       heap_adjust(heap,i,nums);

       printHeap(heap, nums);

    }

}

/*

 2)自上往下的堆调整,对当前pos结点往它的子结点进行调整,保证该结点的值小于其子结点的.

 */

void heap_adjust(int heap[],int pos,int nums){

   for (int i=2*pos+1; i<nums; i=2*i+1) {

       if (i+1<nums&&heap[i+1]<heap[i]) {//在左结点和右结点中找到较小的结点

            i++;

        }

       if (heap[(i-1)/2]>heap[i]) {//较小的结点若比父节点小,则交换

           swap(&heap[(i-1)/2], &heap[i]);

        }

    }

}

void printHeap(int heap[],int n){

   for (int i=0; i<n; i++) {

       printf("%d --- ",heap[i]);

    }

   printf("\n");

}

/*

 堆排序

 步骤:取堆顶元素与最后元素交换,堆长度相应-1,然后调整新堆,当取堆顶次数达到数组元素个数时,这时数组中的元素就是有序的了,这里是从大到小排序,因为每次从堆中取最小元素(最小堆)放在数组后面.(而最大堆得到的堆排序是从小到大的)

 */

void heap_sort(int heap[],int nums){

   if (nums<1) {

       return ;

    }

   Heap_create(heap, nums);

    //printHeap(heap,nums);

   int i ;

   for (i=nums-1; i>=1; i--) {

       swap(&heap[0], &heap[i]);

       heap_adjust(heap, 0, i);

    }

}

int main(int argc,const char * argv[])

{

    

    

   int array[1024*1024]={0};

   int numberOfArray = 0;

   inputArray(array, &numberOfArray); 

    //选择排序

    //    printf(" :");printArray(array, numberOfArray);

    //    select_sort(array, numberOfArray);

    //    printf("选择排序后:");printArray(array, numberOfArray);

    //    printf("\n");  

    //冒泡排序

    //    printf(" :");printArray(array, numberOfArray);

    //    bubble_sort(array, numberOfArray);

    //    printf("选择排序后:");printArray(array, numberOfArray);

    //    printf("\n");    

    //直接插入排序

    //    printf(" :");printArray(array, numberOfArray);

    //    insert_sort(array, numberOfArray);

    //    printf("直接插入排序后:");printArray(array, numberOfArray);

    //    printf("\n");

    //希尔排序

    //    printf(" :");printArray(array, numberOfArray);

    //    shell_sort(array, numberOfArray);

    //    printf("希尔排序后:");printArray(array, numberOfArray);

    //    printf("\n");

    //    //快速排序

    //    printf(" :");printArray(array, numberOfArray);

    //    quick_sort(array, 0,numberOfArray-1);

    //    printf("快速排序后:");printArray(array, numberOfArray);

    //    printf("\n");   

    //堆排序

    //    printf(" :");printArray(array, numberOfArray);

    //    heap_sort(array, numberOfArray);

    //    printf("堆排序后(从大到小):");printArray(array, numberOfArray);

    //    printf("\n");   

   return 0;

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值