算法学习笔记

常见的时间复杂度,按数量级递增排列依次为:常数阶O(1)、对数阶O(log2n)、线性阶O(n)、线性对数阶O(nlog2n)、平方阶O(n2)、立方阶O(n3)、k次方阶O(nk)、指数阶O(2n)。常见的算法时间复杂度由小到大依次为:

                    c < log2N < n < n * Log2N < n^2 < n^3 < 2^n < 3^n < n!

在这里插入图片描述

在这里插入图片描述

冒泡排序

两两比较
两个数字比较

int n = list.size();
for (int i = 0; i < n - 1; ++i)
{
	for (int j = i + 1; j < n; ++j)
	{
		if (list[i] > list[j]) 
			swap(list[i], list[j]);
	}
}

选择排序

选一个最小的,放到最前面。
(优化:可以同时选最大的放最右边)

void SelectSort(){
      for (int i = 0; i < N-1; ++i)
      {
      	int pos =i;
      	for (int j = i+1; j < N; ++j)
      	{
      		if (sque[j]<sque[pos])
      		{
      			pos=j;
      		}      
      	}	
      	if (pos!=i)
      		{
      			int temp=sque[pos];
      			sque[pos]=sque[i];
      			sque[i]=temp;
      		}
      }
}

插入排序

和打扑克牌一样,抽牌后从后面一个个比,大了就放进去。
(优化:用链表排(不移动),带多个元素排,希尔排序)

void insert_sort(int arr[], int len)
 {
    for (int i = 1; i < len; ++i)
    {
      if (arr[i] < arr[i - 1]) {
        int temp = arr[i];   
        for (int j=i-1 ; j>=0 && arr[j]>temp ;--j)
        {
        arr[i] = arr[j];//交换位置
        }
          arr[i] = temp;
          }
        }
  }

希尔排序

1、分2组,排列个数÷2减1 ;
2、两个组对比,小的放前面的组,list1[1]和list2[1]对比交换;
3、分2组,排列个数÷2再÷2减1 ;
最后就是插入排序了
在这里插入图片描述

int shsort(int s[], int n)    /* 自定义函数 shsort()*/
{
    int i,j,d;
    d=n/2;    /*确定固定增虽值*/
    while(d>=1)
    {
        for(i=d+1;i<=n;i++)/*数组下标从d+1开始进行直接插入排序*/
        {
            s[0]=s[i];    /*设置监视哨*/
            j=i-d;    /*确定要进行比较的元素的最右边位置*/
            while((j>0)&&(s[0]<s[j]))
            {
                s[j+d]=s[j];    /*数据右移*/
                j=j-d;    /*向左移d个位置V*/
            }
            s[j + d]=s[0];    /*在确定的位罝插入s[i]*/
        }
        d = d/2;    /*增里变为原来的一半*/
    }
return 0;
}

快速排序

1、随机取一个值,再取 值位置最大size位置指针
取一个比它小的值放在它的值位置上,或者大的,
2、两个指针逼近重叠就排好一个,再取左边一个值循环1操作
在这里插入图片描述
3、区间小于2个元素就不用排了
在这里插入图片描述

int qusort(int s[],int start,int end)    //自定义函数 qusort()
{
    int i,j;    //定义变量为基本整型
    i=start;    //将每组首个元素赋给i
    j = end;    //将每组末尾元素赋给j
    s[0]=s[start];    //设置基准值
    while(i<j)
    {
        while(i<j&&s[0]<s[j])
        j--;    //位置左移
        if(i<j)
        {
            s[i]=s[j];    //将s[j]放到s[i]的位置上
            i++;    //位置右移
        }
        while(i<j&&s[i]<=s[0])
            i++;    //位置左移
        if(i<j)
        {
            s[j]=s[i];    //将大于基准值的s[j]放到s[i]位置
            j--;    //位置左移
        }
    }
    s[i]=s[0];    //将基准值放入指定位置
    if (start<i)
        qusort(s,start,j-1);//对分割出的部分递归调用qusort()函数
    if (i<end)
        qusort(s,j+1,end);
    return 0;
}

归并排列

在这里插入图片描述

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);
}

堆排序

要完整的二叉树(满的,如果有分支要从左边)
在这里插入图片描述
在这里插入图片描述
代码百度

计数排序

1、记下每个数字出现的次数
2、排列回去.

 void coutSort(int* data, int length)
    {
        if (data == nullptr || length <= 0)
            return;
        //确定数列最大值
        int max = data[0];
        for (int i = 1; i < length; ++i)
        {
            if (data[i] > max)
                max = data[i];
        }
        // 确定统计数组长度并进行初始化
        int* coutData = new int[max + 1];
        for (int i = 0; i <= max; ++i)
            coutData[i] = 0;
        // 遍历数组,统计每个数出现的次数
        for (int i = 0; i < length; ++i)
            ++coutData[data[i]];
        // 排序数组,某个数出现了几次,便在data里累计输出几次
        int index = 0;
        for (int i = 0; i <= max; ++i)
        {
            for (int j = 0; j < coutData[i]; ++j)
            {
                data[index++] = i;
            }
        }
    }

桶排序

在这里插入图片描述

void Insert(vector<double> & bkt, double num) {
    for (vector<double>::iterator p = bkt.begin(); p != bkt.end(); ++p)
        if (*p > num) {
            bkt.insert(p, num);
            return ;
        }
    bkt.push_back(num); //没有找到,就放最后
}

void BucketSort(double * const begin, double * const end) {  //假设输入数据都是小数[0,1)
    int n = end - begin;
    int i;
    vector<vector<double>*> bucket(n); //为什么是n个桶,应该和hash一个原理

    for (i = 0; i < n; ++i)
        bucket[i] = new vector<double>;
    for (i = 0; i < n; ++i) { //按顺序插入到桶中
        Insert(*bucket[static_cast<int>(*(begin + i) * n)], *(begin + i));
    }
    int j = 0, k = 0;
    for (i = 0; i < n; ++i) {
        while (k >= bucket[j]->size()) { //如果出现连续的空桶
            ++j;
            k = 0;
        }
        *(begin + i) = (*bucket[j])[k++];
    }
    for (i = 0; i < n; ++i)
        delete bucket[i];
}

基数排序

在这里插入图片描述
在这里插入图片描述

// 获取数组arr中最大值,arr-待排序的数组,len-数组arr的长度。
int arrmax(int *arr,unsigned int len)
{
  int ii,imax;

  imax=arr[0];

  for (ii=1;ii<len;ii++)
    if (arr[ii]>imax) imax=arr[ii];

  return imax;
}

// 对数组arr按指数位进行排序。
// arr-待排序的数组,len-数组arr的长度。
// exp-排序指数,exp=1:按个位排序;exp=10:按十位排序;......
void _radixsort(int *arr,unsigned int len,unsigned int exp)
{
  int ii;
  int result[len];       // 存放从桶中收集后数据的临时数组。
  int buckets[10]={0};   // 初始化10个桶。

  // 遍历arr,将数据出现的次数存储在buckets中。
  for (ii=0;ii<len;ii++)
    buckets[(arr[ii]/exp)%10]++;

  // 调整buckets各元素的值,调整后的值就是arr中元素在result中的位置。
  for (ii=1;ii<10;ii++)
    buckets[ii]=buckets[ii]+buckets[ii-1];

  // 将arr中的元素填充到result中。
  for (ii=len-1;ii>=0;ii--)
  {
    int iexp=(arr[ii]/exp)%10;
    result[buckets[iexp]-1]=arr[ii];
    buckets[iexp]--;
  }
  
  // 将排序好的数组result复制到数组arr中。
  memcpy(arr,result,len*sizeof(int));
}

// 基数排序主函数,arr-待排序的数组,len-数组arr的长度。
void radixsort(int *arr,unsigned int len)
{
  int imax=arrmax(arr,len);    // 获取数组arr中的最大值。

  int iexp;    // 排序指数,iexp=1:按个位排序;iexp=10:按十位排序;......

  // 从个位开始,对数组arr按指数位进行排序。
  for (iexp=1;imax/iexp>0;iexp=iexp*10)
  {
    _radixsort(arr,len,iexp);
    int yy; printf("exp=%-5d  ",iexp); for (yy=0;yy<len;yy++) printf("%2d ",arr[yy]); printf("\n");
  }
}

笔记收藏1041449625

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值