排序代码(python,c++) 及 基本算法复杂度
0.导语
本节为手撕代码系列之第一弹,主要来手撕排序算法,主要包括以下几大排序算法:
直接插入排序
冒泡排序
选择排序
快速排序
希尔排序
堆排序
归并排序
1.直接插入排序
【算法思想】
每一步将一个待排序的记录,插入到前面已经排好序的有序序列中去,直到插完所有元素为止。
【代码实现】
# 直接插入排序
def insert_sort(arr):
length = len(arr)
for i in range(length):
k = i
for j in range(k,0,-1):
if arr[j]<arr[j-1]:
t = arr[j]
arr[j]=arr[j-1]
arr[j-1]=t
arr = [4,3,0,-1]
insert_sort(arr)
print(arr)
2.冒泡排序
【算法思想】
对相邻的元素进行两两比较,顺序相反则进行交换,这样,每一趟会将最小或最大的元素“浮”到顶端,最终达到完全有序。
【代码实现】
# 冒泡排序
def bubbleSort(arr):
length = len(arr)
for i in range(length-1):
flag = True
for j in range(length-i-1):
if arr[j]>arr[j+1]:
t = arr[j]
arr[j]=arr[j+1]
arr[j+1]=t
flag = False
if flag:
break
arr = [6,-2,0,9]
bubbleSort(arr)
print(arr)
3.选择排序
【算法思想】
每一趟从待排序的数据元素中选择最小(或最大)的一个元素作为首元素,直到所有元素排完为止,简单选择排序是不稳定排序。
【代码实现】
def selectSort(arr):
length = len(arr)
for i in range(length-1):
min = i
for j in range(i+1,length):
if arr[min]>arr[j]:
min=j
if min!=i:
t = arr[i]
arr[i]=arr[min]
arr[min]=t
arr = [6,-2,0,9]
selectSort(arr)
print(arr)
4.快速排序
【算法思想】
快速排序思想----分治法。
先从数列中取出一个数作为基准数。
分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
再对左右区间重复第二步,直到各区间只有一个数。
每次划分得到,枢椎的左边比它小,右边比它大。
【代码实现】
方法一(通过遍历直接得到大于pivot和小于pivot的元素):
class Solution:
def quicksort(self, array):
"""
:type numRows: int
:rtype: List[List[int]]
"""
if len(array)<=1:
return array
else:
pivot=array[0]
small=[i for i in array[1:] if i<=pivot]
big=[i for i in array[1:] if i >pivot]
return self.quicksort(small)+[pivot]+self.quicksort(big) //递归法,耗时
方法二(双指针前后移动):
def quickSort(arr,left,right):
# 递归终止条件
if left>right:
return
pivot = arr[left]
i = left
j = right
while i<j:
while i<j and arr[j]>=pivot:
j-=1
while i<j and arr[i]<=pivot:
i+=1
if i<j:
t = arr[i]
arr[i] = arr[j]
arr[j] = t
# 放入枢椎
arr[left] = arr[i]
arr[i]=pivot
# 递归调用左区域
quickSort(arr,left,i-1)
# 递归调用右区域
quickSort(arr,i+1,right) arr = [6,-2,0,9]
quickSort(arr,0,len(arr)-1)
print(arr)
5.希尔排序
【算法思想】
该算法也被称为:缩小增量排序。
希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
【代码实现】
# 希尔排序
def shellSort(arr):
length = len(arr)
# 设置初始增量
gap = length//2
while gap>0:
# 从第gap个元素,逐个对其所在组进行直接插入排序
for i in range(gap,length):
j = i
while j-gap>=0 and arr[j]<arr[j-gap]:
t = arr[j]
arr[j] = arr[j-gap]
arr[j-gap] = t
j-=gap
gap//=2
arr = [6,-2,0,9]
shellSort(arr)
print(arr)
6.堆排序
【算法思想】
堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。
基本思路:
a.将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;
b.将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;(升序方法)
c.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。
【代码实现】
方法1:
class HeapSort:
def heapSort(self, nums):
length = len(nums)
# 从后往前遍历,交换堆顶与最后叶子节点,并依次调整堆,重复操作
for j in range(length-1,0,-1):
# 获取堆顶元素(获取同时,调整堆)
firstNum = self.adjustHeap(nums,j+1)
# 交换最后一个叶子节点与堆顶元素
temp = nums[j]
nums[j] = firstNum
nums[0] = temp
return nums
# 调整堆(最大堆),每次返回最大堆顶元素
def adjustHeap(self,nums,length):
# 最后一个非叶节点
i = length//2 -1
# 从最后一个非叶节点开始调整,构成最大堆
while i>=0:
temp = nums[i]
k = 2*i+1
while k<length:
if k+1<length and nums[k]<nums[k+1]:
k+=1
if nums[k]>temp:
nums[i]=nums[k]
i=k
else:
break
k=2*k+1
nums[i] = temp
i-=1
return nums[0]
s = HeapSort()
nums = [8,9,7,10]
t = s.heapSort(nums)
print(t)
方法2:
def buildMaxHeap(self,arr):
import math
for i in range(math.floor(len(arr) / 2), -1, -1):
self.heapify(arr, i) def heapify(self, arr, i):
left = 2 * i + 1
right = 2 * i + 2
largest = i
if left < arrLen and arr[left] > arr[largest]:
largest = left
if right < arrLen and arr[right] > arr[largest]:
largest = right if largest != i:
self.swap(arr, i, largest)
self.heapify(arr, largest) def swap(self, arr, i, j):
arr[i], arr[j] = arr[j], arr[i] def heapSort(self, arr):
global arrLen
arrLen = len(arr)
self.buildMaxHeap(arr)
for i in range(len(arr) - 1, 0, -1):
self.swap(arr, 0, i)
arrLen -= 1
self.heapify(arr, 0)
return arr
7.归并排序
【算法思想】
归并排序是利用归并的思想实现的排序方法,该算法采用经典的分治策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。
【代码实现】
import math
class Solution:
def mergeSort(self,arr):
if (len(arr) < 2):
return arr
middle = math.floor(len(arr) / 2)
left, right = arr[0:middle], arr[middle:]
return self.merge(self.mergeSort(left), self.mergeSort(right)) def merge(self,left, right):
result = []
while left and right:
if left[0] <= right[0]:
result.append(left.pop(0));
else:
result.append(right.pop(0));
while left:
result.append(left.pop(0));
while right:
result.append(right.pop(0));
return result
来自于wx公众号“光城”。
几种排序算法代码c++版本 (暂无堆排和希尔排序):
#include "../stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include<functional>
#include <map>
#include <iostream>
using namespace std; void BubbleSort(vector<int> &arr){
if (arr.size() <= )
return;
for (int len = arr.size() - ; len >= ; len--){
for (int i = ; i < len; i++){
if (arr[i]>arr[i + ])
swap(arr[i], arr[i + ]);
}
}
} void SelectionSort(vector<int> &arr){
if (arr.size() <= )
return;
for (int i = ; i < arr.size() - ; i++){
int min_index = i;
for (int j = i + ; j < arr.size(); j++){
/*if (arr[j]<arr[j-1]) //每次左边起始位置向前移一个,但是并不能保证一轮下来,左边的数为最小值
swap(arr[j-1], arr[j]);*/
min_index = arr[min_index] < arr[j] ? min_index : j;
}
swap(arr[min_index],arr[i]);
}
} void InsertSort(vector<int> &arr){
if (arr.size() <= )
return;
for (int i = ; i < arr.size(); i++){ //从索引1开始,前面索引0区域为插入空间
for (int j = i - ; j >= && arr[j]>arr[j + ]; j--) //--逆序(直接和插入空间最右(也即最大)的数比较,就可知是否进行插入)
swap(arr[j], arr[j + ]); //不是i,j直接比较 j--决定插入的具体位置,如(1,3,5)2
}
} void QuickSort(vector<int> &arr,int L, int R){
if (L >= R) //递归终止条件
return;
int pivot = arr[L];
int i = L, j = R;
while (i != j){
//先从右边找,否则会报错
while (arr[j] > pivot&&i < j)
j--;
while (arr[i] <= pivot&&i < j)
i++;
if (i < j){
swap(arr[i],arr[j]);
}
}
arr[L] = arr[i];
arr[i] = pivot; //最终pivot位置为i
QuickSort(arr, L, i - );
QuickSort(arr, i + ,R);
} //归并:先拆分为若干子数组,通过merge()对其逐步合并排序
void Merge(vector<int> &arr, int L, int mid, int R){
int i = L, j = mid + ;
vector<int> new_arr;
while (i <= mid&&j <= R){
if (arr[i] <= arr[j])
new_arr.push_back(arr[i]),i++;
else
new_arr.push_back(arr[j]),j++;
}
while (i <= mid)
new_arr.push_back(arr[i]), i++;
while (j <= R)
new_arr.push_back(arr[j]), j++;
for (int k = L, t = ; k <= R; k++, t++) //把值复制回原arr
arr[k] = new_arr[t];
} void MergeSort(vector<int> &arr, int L, int R){
if (L >= R)
return;
else{
int mid = (L + R) / ;
MergeSort(arr, L, mid);
MergeSort(arr, mid + , R); Merge(arr, L, mid, R);
}
} int main(void){ vector<int> array = {, , , , , , , , };
//BubbleSort(array);
//SelectionSort(array);
//InsertSort(array);
//QuickSort(array, 0, array.size() - 1);
MergeSort(array, , array.size() - );
vector<int> vec = array; vector <int>::iterator it;
for (it = vec.begin(); it != vec.end();it++)
cout << *it << endl; getchar();
return ;
}
基本算法复杂度:
参考来源:https://linux.cn/article-7480-1.html





排序代码(python,c++) 及 基本算法复杂度的更多相关文章
- 选择排序之python
选择排序( Selection sort) 1.算法描述: 通过n-i次关键字之间的比较,从n-i+1个记录中选出关键字最小的记录,并和第i(1<=i<=n)个记录进行交换. 对尚未完成排 ...
- 具体knn算法概念参考knn代码python实现
具体knn算法概念参考knn代码python实现上面是参考<机器学习实战>的代码,和knn的思想 # _*_ encoding=utf8 _*_ import numpy as npimp ...
- 编程算法 - 切割排序 代码(C)
切割排序 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 排序切割, 把一个数组分为, 大于k\小于k\等于k的三个部分. 能够使用高速排序的Parti ...
- python实现折半查找算法&&归并排序算法
今天依旧是学算法,前几天在搞bbs项目,界面也很丑,评论功能好像也有BUG.现在不搞了,得学下算法和数据结构,笔试过不了,连面试的机会都没有…… 今天学了折半查找算法,折半查找是蛮简单的,但是归并排序 ...
- python拓展3 常用算法
知识内容: 1.递归复习 2.算法基础概念 3.查找与排序 参考资料: http://python3-cookbook.readthedocs.io/zh_CN/latest/index.html h ...
- 八大排序的python实现
以下是八大排序的python实现,供以后参考,日后扩展 一.插入排序 #-*- coding:utf-8 -*- ''' 描述 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一 ...
- 使用python模拟实现KNN算法
一.KNN简介 1.KNN算法也称为K邻近算法,是数据挖掘分类技术之一.所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表. 2.KNN算法的核心思想是如果一个样本 ...
- Python遗传和进化算法框架(一)Geatpy快速入门
https://blog.csdn.net/qq_33353186/article/details/82014986 Geatpy是一个高性能的Python遗传算法库以及开放式进化算法框架,由华南理工 ...
- 【C#代码实战】群蚁算法理论与实践全攻略——旅行商等路径优化问题的新方法
若干年前读研的时候,学院有一个教授,专门做群蚁算法的,很厉害,偶尔了解了一点点.感觉也是生物智能的一个体现,和遗传算法.神经网络有异曲同工之妙.只不过当时没有实际需求学习,所以没去研究.最近有一个这样 ...
随机推荐
- Python 绘制2016世界GDP地图
2016世界GDP地图 从https://datahub.io/core/gdp#data下载得到json文件. # country_code.py 获取国家二字代码 # 从pygal.maps.wo ...
- C 语言预编译 #if #else
这个方法我一般用来调试的时候用,有时候串口打印信息太多,一条条注释就很麻烦,于是就用这种方法,定义个宏变量,判断宏变量的条件,来达到改变宏变量的值控制那些代码编译,那些不编译的目的,这样就不用一条条代 ...
- JavaScript(DOM编程补充一)
HTML属性的直接调用: 还可以通过getAttribute方法获取属性的值: setAttribute方法: removeAttribute ---------------------------- ...
- BIO、NIO、AIO
一.基础概念 IO操作分为两步:1.发起IO请求:2.执行具体IO操作: 同步和异步的区别是数据访问时进程是否阻塞或者说在执行真正IO操作时,数据能够立即返回就是异步,否则就是同步,同步和异步发生在I ...
- 操作符及SQL函数
本节要点: 掌握 SQL 操作符 l 算术操作符 l 比较操作符 l 逻辑操作符 l 集合操作符 l 连接操作符 l 操作符的优先级 掌握并熟练应用SQL 函数 l 日期函数 l 字符 ...
- ExtJs之Ext.XTemplate:数组填充,访问父对象
<!DOCTYPE html> <html> <head> <title>ExtJs</title> <meta http-equiv ...
- java多线程具体总结
一.Thread.start()与Thread.run()的差别 通过调用Thread类的start()方法来启动一个线程.这时此线程是处于就绪状态,并没有运行.然后通过此Thread类调用方法run ...
- 高校学生学籍系统C++&mysql
/* C++程序设计实践教学环节任务书 一.题目:高校学籍管理系统 二.目的与要求 1. 目的: 1.掌握C++语言基本知识及其编程方法 2.掌握类和对象的基本概念与用法 3.掌握面向对象中的继承与 ...
- 自己动手写CPU之第七阶段(6)——乘累加指令实现思路
将陆续上传本人写的新书<自己动手写CPU>.今天是第29篇.我尽量每周四篇 亚马逊的销售地址例如以下,欢迎大家围观呵! http://www.amazon.cn/dp/b00mqkrlg8 ...
- Oracle DBA优化数据库性能心得
如今的优化己经向优化等待(waits)转型了,实际中性能优化最根本的出现点也都集中在IO,这是影响性能最主要的方面,由系统中的等待去发现Oracle库中的不足.操作系统某些资源利用的不合理是一个比较好 ...