数据结构基础知识

数据结构是以某种形式将数据组织在一起的集合,它不仅存储数据,还支持访问和处理数据的操作。

一、线性表

        线性表是一种最常用且最简单的一种数据结构,实现线性表的方式一般有两种,一种是使用数组存储线性表的元素,即用一组连续的存储单元依次存储线性表的数据元素。另一种是使用链表存储线性表的元素,即用一组任意的存储单元存储线性表的数据元素(存储单元可以是连续的,也可以是不连续的)。

        数组实现的线性表的优点在于可以通过下标来访问或者修改元素,比较高效,缺点是插入和删除的花费和开销较大。

        链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序的。链表油一系列节点组成,这些节点不必在内存中相连。每个节点有数据部分data和链部分next,Next指向下一个节点,这样当添加或者删除时,只需要改变相关节点的Next的指向,效率很高。

       1、链表的一些基本操作

             一、初始化:链表初始化的作用就是生成一个链表的头指针,用来保存即将创建的链表。头指针就是链表的名字,仅仅是个指针而已。头指针内只有指针的元素,并没有数据元素,但头结点除了指针还有数据。头结点是为了操作的统一与方便而设立的,放在第一个有效元素结点(首元结点)之前,其数据域一般无意义(当然有些情况下也可存放链表的长度、用做监视哨等等)。

           二、插入链表结点

                  链表结尾添加结点的步骤就是新建一个链表结点,将其链接到当前链表尾指针。

                  在指定结点后插入结点,比如在A2结点之后插入一个结点,首先我们要新建立一个结点NodeToInsert,然后将新结点的next指针指向A3结点,并且将A2的next指针指向新建立的结点NodeToInsert,切记操作顺序不要改变。如果操作顺序变换一下,先将A2的next指向了新建立的结点,那么我们就丢失了A3的寻址方式。

          三、删除链表结点

                 删除结点包括删除指定位置的结点和指定元素的结点。其基本原理都是先锁定待删除的结点的位置,然后将该结点的后置结点链接到前置结点的next指针处。这样中间这个结点即我们要删除的结点就从原来的链表中脱离开来。

          四、获取链表长度&链表遍历

                  CurrentNode = CurrentNode ->next,查找链表元素或是链表置空,都需要通过遍历链表来实现。

         五、链表逆序

                假设当前有5个结点,head、a1、a2、a3、a4、a5,他们的头指针是head。我们的思路便是将a1作为当前元素一直往后遍历,并且将a1后面的数据依次挪到head之后。   

                

 

         六、判断链表是否有环

               采用快慢指针的方法遍历,二者一定能够在环上相遇,并且此时slow还没有绕环一圈,也就是说一定是在slow走完第一圈之前相遇。又因为在同一个环中fast和slow之间的距离不会大于换的长度,到二者相遇的时候slow一定还没有走完一周(或者正好走完以后,这种情况出现在开始的时候fast和slow都在环的入口处)。

链表的实现还有其它的方式,常见的有循环单链表,双向链表,循环双向链表。 循环单链表 主要是链表的最后一个节点指向第一个节点,整体构成一个链环。 双向链表 主要是节点中包含两个指针部分,一个指向前驱元,一个指向后继元,JDK中LinkedList集合类的实现就是双向链表。 循环双向链表 是最后一个节点指向第一个节点。

      2、栈和队列   

            栈和队列也是比较常见的数据结构,它们是比较特殊的线性表,因为对于栈来说,访问、插入和删除元素只能在栈顶进行,对于队列来说,元素只能从队列尾插入,从队列头访问和删除。普通的队列是一种先进先出的数据结构,而优先队列中,元素都被赋予优先级。当访问元素的时候,具有最高优先级的元素最先被删除。

二、非线性数据结构

       树型结构是一类非常重要的非线性数据结构,其中以树和二叉树最为常用。

       树是由N个有限结点组成一个具有层次关系的集合。它具有以下特点:每个节点有零个或多个子节点;没有父节点的节点称为 根 节点;每一个非根节点有且只有一个 父节点 ;除了根节点外,每个子节点可以分为多个不相交的子树。          

      1、二叉树

          二叉树是每个节点最多有两棵子树的树结构。通常子树被称作“左子树”和“右子树”。二叉树常被用于实现二叉查找树和二叉堆。

          二叉树的特点:1、每个结点至多只有2棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。

                                    2、第i层至多有2^(i-1)个结点;深度为k的二叉树至多有2^k-1个结点

                                    3、一棵深度为k,且有2^k-1个节点的二叉树称之为 满二叉树

          完全二叉树:深度为k,有n个节点的二叉树,当且仅当其每一个节点都与深度为k的满二叉树中,序号为1至n的节点对应时,称之为 完全二叉树

         三种遍历方法:在二叉树的一些应用中,常常要求在树中查找具有某种特征的结点,这就涉及到遍历 

         1、先序遍历   先访问根结点,再先序遍历左子树,最后先序遍历右子树

         2、中序遍历   先中序遍历左子树,再访问根结点,最后中序遍历右子树

         3、后序遍历   先后序遍历左子树,再后序遍历右子树,最后访问根结点

   2、二叉树查找

        二叉查找就是二叉排序树,也叫二叉搜索树,二叉查找树或者是一棵空树,或者是具有下列性质的二叉树: (1) 若左子树不空,则左子树上所有结点的值均小于它的根结点的值;(2) 若右子树不空,则右子树上所有结点的值均大于它的根结点的值;(3) 左、右子树也分别为二叉排序树;(4) 没有键值相等的结点。

  3、二叉查找树中删除结点  

       要在二叉查找树中删除一个元素,首先需要定位包含该元素的节点,以及它的父节点。假设current指向二叉查找树中包含该元素的节点,而parent指向current节点的父节点,current节点可能是parent节点的左孩子,也可能是右孩子。这里需要考虑两种情况:

       1、current节点没有左孩子,那么只需要将patent节点和current节点的右孩子相连。

       2、current节点有一个左孩子,假设rightMost指向包含current节点的左子树中最大元素的节点,而parentOfRightMost指向rightMost节点的父节点。那么先使用rightMost节点中的元素值替换current节点中的元素值,将parentOfRightMost节点和rightMost节点的左孩子相连,然后删除rightMost节点。

    4、平衡二叉树

         它的左子树和右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。

    5、红黑树

         红黑树是平衡二叉树的一种,它保证在最坏情况下基本动态集合操作的事件复杂度为O(log n)。红黑树和平衡二叉树区别如下:(1) 红黑树放弃了追求完全平衡,追求大致平衡,在与平衡二叉树的时间复杂度相差不大的情况下,保证每次插入最多只需要三次旋转就能达到平衡,实现起来也更为简单。(2) 平衡二叉树追求绝对平衡,条件比较苛刻,实现起来比较麻烦,每次插入新节点之后需要旋转的次数不能预知。

                                                                      

posted @ 2019-06-02 23:29  小妮子的奋斗时代  阅读(216)  评论(0编辑  收藏  举报