快排:左边比key小,右边比key大
当cur找到比key小的值++prev,自己跟自己交换没有意义,cur再往后走,遇见小的++prev,如果比key大++cur,直到遇到比key小, ++prev,交换
cur往后再找,又遇到小的,++prev,交换,小的往左边换,大的往右边
再把prev和key位置交换,
partsort2:
为了防止自己跟自己交换
递归改非递归:,递归调用栈帧,用栈帧模拟,看深度深不深,和数据多少没关系,因为栈帧是可以重复利用的
递归中栈帧里面村的核心数据是什么,区间。 0-9存到栈取出栈,单趟排序,排完压栈
为什么是右左不是左右,栈是后进先出,先入右,先取到左,这样先处理左边,如果先入左,就要先处理右边剩1个0个值没必要入栈了
3-4再单趟排假设在4,左3-3,右5-4,不用进了,再取6-9
这里不会栈溢出,函数调用调用栈帧,在栈区域,,而数据结构内存不够了是去堆申请,堆比栈远远大
每次一个区间才8字节,这1 2G能存很多很多区间,所以非递归问题不大,如果用队列是一层一层排序
栈是深度优先遍历,一边走完走另一边,队列是一层一层把stcakc h添加进来
小于end相当于最少两个值
递归相当于非递归,栈模拟递归,
栈dfs,队列bfs(一层走完走下一层)
归并排序:前提是左区间有序右区间有序
如果四个没有序,那就分成两个和两个,两个也不行,分成一个,一个和一个有序,取小尾插
_函数是子函数,
子问题递归,先把逻辑写出来
拷贝的是begin+end这个区间,比如说第二组数据拷贝回去就只是中间一段区间
会死循环,栈溢出,除本就会丢数据,左区间又-1,右区间可能不变5-9出现问题
就行了
真正有序发生在往回退的过程。后序
归并的时间复杂度:每一层归并是N,总共logN 层
归并排序非递归:也可以用栈,但是快排是前序(排完入栈),这里是后序。0-3,0-3入栈,0-3取出来,分割1,2-3,0-1,入栈 ,0-1取出来0-0就不入了1-1也不入了2-3出来2-2 3-3不入,栈空了,到底拿谁归,
改非递归可以用栈模拟,也可以直接用循环处理
i是起始位置,这一组有gap个,是左闭右闭就得-1
i换成j后面也是,别混了
每次归并的起点就是i,每组归并多少个
每次归并下来就拷贝回去,这样1 1归就搞定了
每一组归是ON外面循环1*2*2*2*。。。=N结束,1乘了logN 次2里面是N次,外面是logN 次
这只能对2的次方倍进行归并,剩下的存在越界问题
看看有什么情况,把每组归并的区间都打印出来
只有begin1不会越界
gap不能变,大逻辑不能变,只考虑越界问题
这两个数本来就有序,不用管
为什么要归并一段,拷贝一段
越界的话没有归并不需要拷贝,如果拷贝放到外面,最后,8.9位置也会拷贝进去,反而出问题