当前位置: 首页 > wzjs >正文

青海做网站哪家好搜索引擎大全网站

青海做网站哪家好,搜索引擎大全网站,成都网站建设公司官网,用c 做网站在Linux上目录 1.前置知识 题目:重新排列数组 代码 提交结果 2.归并排序算法 复制的细节说明 时间复杂度 递归算法代码 1.二分区间,一一往下递归 2.两区间归并 3.返回条件 4.完整代码 递归调用展开图 5.思考题:如果元素的总个数不是偶数个 1.前置知识 题目:重新排列数组 …

目录

1.前置知识

题目:重新排列数组

代码

提交结果

2.归并排序算法

复制的细节说明

时间复杂度

递归算法代码

1.二分区间,一一往下递归

2.两区间归并

3.返回条件

4.完整代码

递归调用展开图

5.思考题:如果元素的总个数不是偶数个


1.前置知识

题目:重新排列数组

https://leetcode.cn/problems/shuffle-the-array/description/

给你一个数组 nums ,数组中有 2n 个元素,按 [x1,x2,...,xn,y1,y2,...,yn] 的格式排列。

请你将数组按 [x1,y1,x2,y2,...,xn,yn] 格式重新排列,返回重排后的数组。

示例 1:

输入:nums = [2,5,1,3,4,7], n = 3
输出:[2,3,5,4,1,7] 
解释:由于 x1=2, x2=5, x3=1, y1=3, y2=4, y3=7 ,所以答案为 [2,3,5,4,1,7]

示例 2:

输入:nums = [1,2,3,4,4,3,2,1], n = 4
输出:[1,4,2,3,3,2,4,1]

示例 3:

输入:nums = [1,1,2,2], n = 2
输出:[1,2,1,2]

提示:

  • 1 <= n <= 500
  • nums.length == 2n
  • 1 <= nums[i] <= 10^3

代码

直译题目即可,选择另外开辟空间存储重新排列好的结果,之后拷贝回去的算法

/*** Note: The returned array must be malloced, assume caller calls free().*/
int* shuffle(int* nums, int numsSize, int n, int* returnSize) 
{int* arr=(int*)malloc(sizeof(int)*2*n);int i=0;int j=0;while(i<n){arr[j]=nums[i];arr[j+1]=nums[i+n];j+=2;i++;}*returnSize=numsSize;return arr;
}

提交结果

2.归并排序算法

归并(Merge)含义:合并,而归并排序(Merge-Sort)是建立在归并操作上的一种排序算法.

算法的核心是分而治之(Divide and Conquer),即先使每个子序列有序,再使子序列段间有序,最后将已有序的子序列合并.得到完全有序的序列

例如给定一个无序含偶数个元素的数组arr={10,6,7,1,3,9,4,2},要求排升序,采用归并算法

发现数组有偶数个元素,因此可以均分,这种归并算法相对于含奇数个元素的数组较容易处理

均分的子序列分别为 {10,6,7,1}、{3,9,4,2}

但是拆分后的子序列并不有序,于是继续均分(递归)(不建议使用插入排序,速度太慢)

均分的子序列分别为 {10,6}、{7,1}、{3,9}、{4,2}

 但是拆分后的子序列并不有序,于是继续均分

 均分的子序列分别为 {10}、{6}、{7}、{1}、{3}、{9}、{4}、{2}

只含一个元素的子序列认为是有序的,于是停止均分

接着回归: 将子序列的左右的有序(左区间有序和右区间有序)部分合并成有序子序列,方法:依次比较,小的尾插到新空间(开一个临时数组,将归并的结果复制回去)

(调整顺序后合并,后将临时数组中的数据拷贝回原数组) 

再 

一个元素和一个元素归并-->两个元素和两个元素归并-->四个元素和四个元素归并-->......

可以看到整体的思路是先分解再合并

复制的细节说明

时间复杂度

每一层需要将归并好的结果尾插到临时开辟的空间,需要操作N个数,递归的层数为logN,两者相乘即为O(NlogN)

递归算法代码

因为是递归,所以需要用到子函数,大致的框架为

#include <stdio.h>
void _mergesort(int* arr, int* tmp,int begin,int end)//要排序的闭区间[begin,end]
{//......
}void mergesort(int* arr, int size)
{//动态开辟临时数组int* tmp = (int*)malloc(sizeof(int) * size);if (tmp == NULL){perror("malloc fail");return;}_mergesort(arr,tmp,0,size-1);//传递要排序的闭区间[0,size-1]free(tmp);tmp = NULL;
}int main()
{int arr[] = {10,6,7,1,3,9,4,2};mergesort(arr, sizeof(arr) / sizeof(int));return 0;
}

下面重点实现子函数_mergesort:

核心思想:先递归后归并

1.二分区间,一一往下递归

void _mergesort(int* arr, int* tmp,int begin,int end)//要排序的闭区间[begin,end]
{//返回条件://...... //二分区间,mid为分完后两区间的边界int mid = (begin + end) / 2;//[begin,mid]和[mid+1,end],下面递归两区间_mergesort(arr, tmp, begin, mid);_mergesort(arr, tmp, mid + 1, end);//归并//......
}

2.两区间归并

初始化时,设指针begin1和end1分别指向第一个区间的首尾元素;指针begin2和end2分别指向第二个区间的首尾元素,可画图为:

利用前置知识讲的重新排列数组的算法,将归并的结果先拷贝到临时数组中,再将临时数组中的结果拷贝回原数组

先拷贝到临时数组中:

设指针i遍历原数组

int begin1 = begin, end1 = mid;
int begin2 = mid + 1, end2 = end;
int i = begin;//<=的原因:是闭区间.当begin1==end1或begin2==end2时,闭区间有一个元素
//可能存在左右区间有一个提前结束的情况,因此写的是&&
while (begin1 <= end1 && begin2 <= end2)
{if (arr[begin1] < arr[begin2])tmp[i++] = arr[begin1++];elsetmp[i++] = arr[begin2++];
}//不知道上个循环因为什么条件退出,因此判断两次
while (begin1 <= end1)tmp[i++] = arr[begin1++];
while (begin2 <= end2)tmp[i++] = arr[begin2++];

 再将临时数组中的结果拷贝回原数组:

因为是闭区间[begin,end],所以一共有end - begin + 1个元素需要拷贝

//注意必须要+begin,位置要对应上,不一定begin为0!
memmove(arr+begin, tmp+begin, sizeof(int) * (end - begin + 1));

3.返回条件

当begin >= end时,函数返回,注意不是begin>end!!

if (begin >= end)return;

如果begin==end仍然循环,计算出来的mid=(begin+end)/2=(2*begin)/2=begin

两个区间为[begin,begin]和[begin+1,begin],第二个区间是不存在的!

4.完整代码

代码添加了一些调试信息,利于分析复杂的多层递归

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void _mergesort(int* arr, int* tmp,int begin,int end)//要排序的闭区间[begin,end]
{//返回条件:if (begin >= end)return;//二分区间,mid为分完后两区间的边界int mid = (begin + end) / 2;printf("递推: [%d,%d] [%d,%d]\n", begin, mid, mid+1, end);//[begin,mid]和[mid+1,end],下面递归两区间_mergesort(arr, tmp, begin, mid);_mergesort(arr, tmp, mid + 1, end);//归并int begin1 = begin, end1 = mid;int begin2 = mid + 1, end2 = end;int i = begin;printf("回归: [%d,%d] [%d,%d]\n", begin1, end1, begin2, end2);//<=的原因:是闭区间.当begin1==end1或begin2==end2时,闭区间有一个元素//可能存在左右区间有一个提前结束的情况,因此写的是&&while (begin1 <= end1 && begin2 <= end2){if (arr[begin1] < arr[begin2])tmp[i++] = arr[begin1++];elsetmp[i++] = arr[begin2++];}//不知道上个循环因为什么条件退出,因此判断两次while (begin1 <= end1)tmp[i++] = arr[begin1++];while (begin2 <= end2)tmp[i++] = arr[begin2++];memmove(arr+begin, tmp+begin, sizeof(int) * (end - begin + 1));//拷贝回原数组}void mergesort(int* arr, int size)
{//动态开辟临时数组int* tmp = (int*)malloc(sizeof(int) * size);if (tmp == NULL){perror("malloc fail");return;}printf("debug info:\n");_mergesort(arr,tmp,0,size-1);//传递要排序的闭区间[0,size-1]free(tmp);tmp = NULL;
}int main()
{int arr[] = {10,6,7,1,3,9,4,2};mergesort(arr, sizeof(arr)/sizeof(int));for (int i = 0; i < sizeof(arr) / sizeof(int); i++)printf("%d ", i);return 0;
}

 运行结果:

递归调用展开图

依照debug info的内容可以画出递归调用展开图,设递推用蓝色箭头,回归用绿色箭头

如果是16个数(为2的次方)排序,例如:int arr[] = {10,6,7,1,3,9,4,2,234,565,4,2,89,12,78,324};

结果为:

5.思考题:如果元素的总个数不是偶数个

仍然可以归并排序,只不过是不完全二分(可以理解为近似二分)

将代码提交到LeetCode的912. 排序数组题上:

void _mergesort(int* arr, int* tmp,int begin,int end)
{if (begin >= end)return;int mid = (begin + end) / 2;_mergesort(arr, tmp, begin, mid);_mergesort(arr, tmp, mid + 1, end);int begin1 = begin, end1 = mid;int begin2 = mid + 1, end2 = end;int i = begin;while (begin1 <= end1 && begin2 <= end2){if (arr[begin1] < arr[begin2])tmp[i++] = arr[begin1++];elsetmp[i++] = arr[begin2++];}while (begin1 <= end1)tmp[i++] = arr[begin1++];while (begin2 <= end2)tmp[i++] = arr[begin2++];memmove(arr+begin, tmp+begin, sizeof(int) * (end - begin + 1));
}void mergesort(int* arr, int size)
{int* tmp = (int*)malloc(sizeof(int) * size);_mergesort(arr,tmp,0,size-1);
}int* sortArray(int* nums, int numsSize, int* returnSize) 
{*returnSize=numsSize;mergesort(nums,numsSize);return  nums;
}

提交结果:

下篇文章讲讲非递归算法的代码 

http://www.dtcms.com/wzjs/218372.html

相关文章:

  • 备案期间 需要关闭网站360推广登陆入口
  • 3d效果图教程网站市场营销策划案的范文
  • 德州宁津网站建设网络营销师主要做什么
  • 网络工程就业前景分析百度seo优化排名客服电话
  • 做公关用的网站网站如何赚钱
  • 跑腿个人网站怎么做seo优化的内容有哪些
  • 合肥网站建设制作成crm软件
  • 网站交互做的比较好的百度关键词关键词大全
  • gta5网站建设中什么意思网络营销课程实训总结
  • 美国成年做爰网站青岛网站建设与设计制作
  • 欧洲男女做受视频网站哪个平台可以买卖链接
  • 中小企业网站建设方案google免费入口
  • 苏州广告公司招聘官网seo
  • 全国建设地产网站百度推广页面投放
  • 公司免费网站搭建找seo外包公司需要注意什么
  • 基于c 的视频网站开发网络营销推广网站
  • 哈尔滨网站制作公司哪家好营销策略有哪些有效手段
  • 寻找项目做的网站什么是网络软文营销
  • 今日足球赛事分析推荐seo新人怎么发外链
  • 科技网站建设的调研百度站长链接提交
  • 英孚做测试的网站京东关键词优化技巧
  • 九江网站推广黄页网络的推广网站有哪些类型
  • 东道设计是4a公司吗搜索引擎优化 简历
  • 网站首页排名下降搜索优化引擎
  • 安徽动漫公司 网站制作 安徽网新域名购买平台
  • 湖南人文科技学院怎么样太原seo报价
  • wordpress标签怎么做静态化优化大师官网登录入口
  • 网页制作的公司有哪些seo推广案例
  • 建设一个地方门户网站快速建站平台
  • 买个网站服务器多少钱百度公司好进吗