为什么要写这篇
1.前段什么时间复习了一下数据结构,学习了一遍,又有了进一步的认识。说排序之前,先简单的总结一下数据结构。
数据目前分为线性结构和非线性结构;
线性结构
线性结构是最常用的数据结构,其特点是数据元素之间存在一对一的线性关系。按照存储结构又分为2种,一种是顺序存储(地址是连续的),一种是链式存储结构(地址不连续,但是每一块存储下一块的首地址)。
具体的就不在阐述,这篇文章写得很详细了
https://www.cnblogs.com/mr-wuxiansheng/p/8688946.html
非线性结构
一个典型结构就是树结构,开始我还不是很深刻的理解,最后我发现其实这些基本的东西都是有关联的,树结构相当于是链式结构的进化体了,他让线成了树,将结构变得有规律并且复杂了起来,最简单的就是二叉树,复杂的树就需要链表来搭建。
这里我们就简单说一下树的遍历,只有遍历了,你才能更好的对二叉树进行插入,删除,修改。
D代表根结点 ,L代表左子树,R代表右子树
有6遍历方案:DLR、LDR、LRD、RDL、RLD、LRD,
用的最多是前三种及先序遍历(DRL)、中序遍历(LDR)、后序遍历(LRD)
以先序遍历为例,后面其实都可以照搬方法
1先“访问”根结点
2先序遍历左子树
3先序遍历右子树
伪代码 (其实用c或者c++ 更能体现底层)
//二叉树结构
public class TreeNode{
TreeNode left;
String data;
TreeNode right;
}
//递归算法
dlr(TreeNode tree){
if(tree){
print(tree.data);
dlr(tree.left);
dlr(tree.right);
}
}
后面2种无非就是递归里面方法换个位置。
前面写了这么多也是为了给归并排序做个铺垫,看似没联系,其实我觉得还是有关联。
归并排序字面上就是说先分在合,先一个个划分,排序,在进行合并,很神奇的是最后排序成功了。
具体操作步骤
我们以最简单的数组为例吧 3,5,6,4,2,1
首先将数组拆分2组 left 3,5,6 right 4,2,1
拆分2组我们继续拆
1.left 3,5 right 6
2.left4,2 right 1
按照上述步骤继续拆下去,拆到只剩一个为止,然后就是合并,思路图如下
合并时候进行比较,较小的放到一个空数组,如果左右有剩余,现将左边放到之前空数组,然后放右边
最后上java代码
public class Test{
private Integer[] nums = {3,8,9,10,7,6,5,2,4,1,11,12};
@Test
public void test() {
devideSortArray(0,nums.length-1);
}
public void devideSortArray(Integer begin,Integer end){
if (begin<end){
Integer mid = (Integer)(begin+end)/2;
System.out.print("获得"+begin+"---"+mid+"---"+end+"\n");
devideSortArray(begin,mid);
devideSortArray(mid+1,end);
caculate(begin,mid,end,nums);
}
}
public Integer[] caculate(Integer begin,Integer mid,Integer end,Integer[] showNum){
Integer[] tempNum =new Integer[end+1];
int k = begin;
int left = begin;
int right = mid+1;
int cur = showNum[k];
while (left <= mid && right <=end){
if (showNum[left]>showNum[right]){
tempNum[k] = showNum[right];
right++;
k++;
}else {
tempNum[k] = showNum[left];
left++;
k++;
}
}
//左边有剩余 加入数组中
while (left<=mid){
tempNum[k] = showNum[left];
left++;
k++;
}
//右边有剩余 加入数组中
while (right<=end){
tempNum[k] = showNum[right];
k++;
right++;
}
int b = begin;
int e = end;
System.out.print("排列数--->>>>>>>\n");
for (int i = 0; i < tempNum.length; i++) {
if (tempNum[i] != null){
System.out.print("---"+tempNum[i]);
showNum[b] = tempNum[i];
b++;
}
}
System.out.print("<<<<<<<<<<\n");
return tempNum;
}
}
打印效果如下
获得0---5---11
获得0---2---5
获得0---1---2
获得0---0---1
排列数--->>>>>>>
---3---8<<<<<<<<<<
排列数--->>>>>>>
---3---8---9<<<<<<<<<<
获得3---4---5
获得3---3---4
排列数--->>>>>>>
---7---10<<<<<<<<<<
排列数--->>>>>>>
---6---7---10<<<<<<<<<<
排列数--->>>>>>>
---3---6---7---8---9---10<<<<<<<<<<
获得6---8---11
获得6---7---8
获得6---6---7
排列数--->>>>>>>
---2---5<<<<<<<<<<
排列数--->>>>>>>
---2---4---5<<<<<<<<<<
获得9---10---11
获得9---9---10
排列数--->>>>>>>
---1---11<<<<<<<<<<
排列数--->>>>>>>
---1---11---12<<<<<<<<<<
排列数--->>>>>>>
---1---2---4---5---11---12<<<<<<<<<<
排列数--->>>>>>>
---1---2---3---4---5---6---7---8---9---10---11---12<<<<<<<<<<
大功告成,发现跟二叉树算法遍历还是有很多相似之处。
最后总结,学好基础很重要,关联着学习,更加受益。