IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 分治思想及例题 -> 正文阅读

[数据结构与算法]分治思想及例题

主旨思想

分治思想主旨就是“分而治之”,大概就是指将一个规模较大的问题分割成规模较小的同类问题,然后再将这些小的子问题,逐个解决,最终大问题也就解决掉了。通常分治和递归是一起用的。

例题

二分法查找

二分法查找算法是一种提现分治思想的算法。
力扣题目链接:704. 二分查找
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

示例 1:
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4

示例 2:
输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-search
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


思路

二分法查找算法的思路的前提是数组有序的,将上面数组从中间一分为二,然后用中间middle值和target目标值进行比较:

  1. 如果中间的数大于target目标值,那么target就可能在左边数组当中,然后把中间middle-1赋值给右边right的值,再从左边数组中寻找新的中间middle值和target目标值进行比较
  2. 如果中间的数小于target目标值,那么target就在可能右边数组当中,然后把中间middle+1赋值给左边left的值,再从边数组中寻找新的中间middle值和target目标值进行比较

例如示例 1:中用图表示:

在这里插入图片描述


非递归写法

javascript:

var search = function(nums, target) {
    let left = 0, right = nums.length-1;//定义左右边界[left,right]
    while(left <= right)//当left = right,依然是在[left,right]区间当中
    {
        let mid =left + Math.floor((right - left)/2);//计算中间值,防止溢出,等效于(left+right)/2,后面这种写法可能会导致溢出如果right特别大,但是没有越界,left特别大,但也没有越界,但是你把他俩相加就有可能越界。
        if(nums[mid] > target)
        {
            right = mid - 1;//target可能在左区间[left,mid - 1]之间,所以更新右边界right = mid - 1;
        }
        else if(nums[mid] < target)
        {
            left = mid + 1;//target可能在右区间[mid + 1,right]之间,所以更新左边界边left = mid + 1;
        }
        else//(nums[mid] ==  target)
        {
            return mid;//找到目标值,返回结果
        }
    }
    return -1;//没有找到目标值,按题意返回-1
};

递归写法

C:

int recursion(int *nums, int target, int left, int right)
{
    if(left > right)
    {
        return -1;//递归出口,没有找到值
    }
    else
    {    
        int mid = left + (right - left)/2;
        if(target < nums[mid])
        {
            return recursion(nums, target, left, mid - 1);
        }
        else if(target >  nums[mid])
        {
            return recursion(nums, target, mid + 1, right);
        }
        else
        {
            return mid;
        }
    }
}
int search(int* nums, int numsSize, int target){
    int left = 0, right = numsSize - 1;
    return recursion(nums, target, left,  right);//调用递归,并且把值返回出去。
}

快速排序算法

基本思想

快速排序用到了分而治之的思想。

  1. 先从数组中找到一个数,可以是是任取待排序序列的一个元素作为中心元素(可以用第一个,最后一个,也可以是中间任何一个),习惯将其称为pivot枢轴元素;
  2. pivot将数组分成两个数组:
    • 将所有小于pivot的数放在其左边;
    • 将所有大于pivot的数在其右边;
  3. 然后对两个新的数组按照上面的算法继续排序。

例如:
数组 [ 21, 15, 34 , 10, -3, 1 , 16 , 44, 10, 49];

  1. 定义一枢轴元素pivot,即为21;
  2. 定义一左边指针的为left;
  3. 定义一右边指针的为right。
  4. 然后从右边往左边找比pivot小的数
  5. 把指针right所指的值赋值给left
    在这里插入图片描述

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

直到
在这里插入图片描述
这样第一趟的排序就完成了,通过pivot将数组分成了[10,15,16,10,-3,1] 与 [44, 34, 49]左右两部分,然后分别对这两个数组重新用相同的算法,直到只剩下一个元素。


代码

javascript:

function partition(arr, left, right) {
    var pivot = arr[left];//初始化pivot为数组第一个数;
    while (left < right) {//只要left还小于right就进行循环;
        while (left < right && arr[right] >= pivot) {//先从右边找一个比枢轴元素pivot小的数
            right--;
        }
        arr[left] = arr[right];//将当前left所指的数赋值给right
        while (left < right && arr[left] <= pivot) {//从左边找一个比枢轴元素pivot大的数
            left++;
        }
        arr[right] = arr[left];//将当前right所指的数赋值给left
    }
    arr[right] = pivot;//将pivot值赋值给当前right
    return right;//返回索引
}
function quickSort(arr, left, right) {
	var middle;
    if (left < right) {
    	middle = partition(arr, left, right);//如果left比right小,进行一次划分,将返回来的值赋值给middle;
        partition(arr, mid + 1, right);//对middle + 1到right的部分进行一次快排(递归进行)
        partition(arr, left, mid - 1);//对left到middle - 1的部分进行一次快排(递归进行)
    }
}

/*------------------------测试代码-----------------------------------*/

var arr =  [ 21, 15, 34 , 10, -3, 1 , 16 , 44, 10, 49];
console.log("排序前的数组:", arr)


quickSort(arr, 0, arr.length - 1);
console.log("排序后的数组", arr);

在这里插入图片描述


时间和空间复杂度分析

时间复杂度:

  1. 理想的情况:时间复杂度为O(nlogn)
  2. 最坏情况:O(n2),这种情况是退化成冒泡排序

**空间复杂度:**根据实现的方式不同而不同
稳定性:不稳定

归并算法

基本思想

归并算法也是分而治之的思想(分治法) 。
例子
输入数组 [ 2, 5, 3 , 10, -3, 1 , 6 , 4];
分治思想如下:
在这里插入图片描述

代码

function merge(arr, left, mid, right, temp) {
    var i = left;
    var j = mid + 1;
    var t = 0;
    while (i <= mid || j <= right) {
        if (i > mid) {
            temp[t++] = arr[j++];
        }
        else if (j > right) {
            temp[t++] = arr[i++];
        }
        else {
            if (arr[i] <= arr[j]) {
                temp[t++] = arr[i++];
            }
            else {
                temp[t++] = arr[j++];
            }
        }
    }
    var k = left;
    t = 0;
    while (k <= right) {
        arr[k++] = temp[t++]
    }
}

function mergeSort(arr, left, right, temp) {
    if (left < right) {
        var mid = Math.floor((left + right) / 2);//中间索引
        mergeSort(arr, left, mid, temp);//左边递归分解
        mergeSort(arr, mid + 1, right, temp);//右边递归分解
        merge(arr, left, mid, right, temp);//合并
    }
}
/*------------------------测试代码--------------------*/

var arr = [2, 5, 3, 10, -3, 1, 6, 4];
var temp = new Array(arr.length);
console.log("排序前:", arr);
mergeSort(arr, 0, arr.length - 1, temp);
console.log("排序后:", arr);

在这里插入图片描述

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-11-23 12:37:09  更:2021-11-23 12:37:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/9 16:18:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码