绪:
~~写在前面的:
~~在堆代码之前::
我认为先了解梳理基础的数据结构问题,以及解决一些存在疑问的地方很有必要!!!
EIGHT QUESTIONS:
NO.1 数据结构??!:
指的是相互之间存在的一种或者多种关系的数据元素的集合以及在此集合中数据元素之间的关系。
NO。2 这些关系都指的是什么??!
这些元素和元素之间的相互关系包括三个部分:
数据的逻辑结构,数据的存储结构和数据的运算结构。
逻辑结构:具有四种不同的基本类型:树型,网状型,集合型,线性。
NO.3 数据结构在使用的时候都有哪些意义??!
在一个数据集合中的各个数据元素之间存在一定的关系,而这些逻辑关系就是数据的逻辑结构。所以在确立了一定逻辑结构的基础上对于算法的确立会提供极大的便利。也使得算法在所确定的逻辑结构中可以更好的适应。
了解了数据结构在使用过程中的意义,难免会引起我们去思考>>>
???NO.4 利用计算机在对数据进行处理,解决一个问题的时候都需要经过哪些步骤呢???
1.首先在具体的问题中找出相应的数学模型。(在此过程中无法利用数学方程描述方式对问题将进行描述,需要使用到数据结构的方式去描述这个需要提取的数学模型)
2.其次根据所描述的数学模型制定合适的算法来解决相应的问题。
3.再来对于相应的程序进行编写
4.对程序进行调试,修改完善。
???NO.5 所谓的结点是什么???
在计算机中最小的单位是二进制数的一位,被称为位。将若干个位组合起来形成的位串,而这些位串构成的数据元素称为结点或者元素。
???NO.6 所谓的数据域是什么???
当数据元素由若干个数据项组成时,位串中与各个数据项相对应的子位串称为数据域。
???NO.7 对于同一种数据结构如果所采用的操作方式不同对于数据所产生的结果是否不同???
对于同一种数据结构操作方式的不同所产生的结果截然不同。但是尽管数据结构的操作集合有所区别。
但是有一些操作是必须存在的:
“<1>结构的产生。<2>结构的销毁。<3>在数据结构中找出满足条件的数据元素。<4>在结构中插入新的数据元素。<5>在结构中删除数据元素。<6>遍历”
???NO.8 比较常用的数据结构都有哪些???
数组,链表,队列,栈,树,图,堆。(省略具体的含义,随着后续学习进行跟进)。
对于数据结构有了大致整体的了解之后,开始进行对于单个数据结构类型的学习。
正文:
链表的含义:是一种非连续,非顺序的存储结构,它可以用来表示线性结构,也可以用来表示非线性的结构。其中数据元素的逻辑顺序是由指针的链接次序实现。链表由一系列的结点组成(每一个数据元素就是一个结点)。每一个结点都可以动态生成,其中的结点由两个部分组成; 数据域 & 指针域。
链表分为三种:单链表,双向链表,循环链表。
单链表:
循环链表:
和单链表一样地方的是线性表的存储方式。和单链表不同的地方是循环链表的表头结点被最后一个结点的指针指向。
(指针:是编程语言中的一个对象,利用地址,它的值直接指向存在电脑存储器中另一个地方的值。)
双向链表:
收到单链表结点的结构的限制,对某一个结点进行前驱操作时必须从表头开始查找。而双向链表既有存储直接后继结点地址的链域,又有存储直接前驱结点地址的链域的这样一个双链域结点结构。
链表在Java中的实现:
//定义一个类Node,Node实例代表链表的节点
public class Node{
//保存节点的数据
private T data;
//指向上一个节点的引用
private Node prev;
//指向下一个节点的引用
private Node next;
}
考虑到双向链表的结构,设置头结点和尾结点
//保存该链表的头结点
private Node header;
//保存该链表的尾节点
private Node tail;
//保存该链表中已包含的节点数
private int size
设置根据索引index找到制定位置结点的方法
public Node getNode(int index){
if(index < 0 || index > size -1){
throw new IndexOutOfBoundsException("线性表索引越界");
}
if(index < (size >> 1)){
//从header节点开始遍历
Node current = header;
for(int i=0; i < index; i++){
current = current.next;
}
return current;
}else{
Node current = tail;
for(int i = size - 1; i > index; i--){
current = current.prev;
}
return current;
}
}
在表头插入一个元素的方法:
public void addFirst(T element){
linkFirst(element);
}
public void linkFirst(T element){
Node f = header;
Node newNode = new Node(element,null,f);
header = newNode;
if(f == null){
tail = newNode;
}else{
f.prev = newNode;
}
size++;
}
在表尾插入元素的方法:
public void linkTail(T element){
Node t = tail;
Node newNode = new Node(element, t, null);
tail = newNode;
if(t == null){
header = newNode;
}else{
t.next = newNode;
}
size++;
}
在某一个元素之前加入结点的方法:
public void linkBefore(T element, Node node){
Node pre = node.prev;
Node newNode = new Node(element, pre, node);
node.prev = newNode;
if(pre == null){
header = newNode;
}else{
pre.next = newNode;
}
size++;
}
移走头(尾)结点的方法:
public void removeFirst(){
Node first = header;
if(first == null)
throw new NoSuchElementException("此结点被移除");
unlinkFirst(first);
}
删除元素的方法:
public void unlink(Node node){
Node pre = node.prev;
Node next = node.next;
node.data = null;
if(pre == null){
header = next;
}else{
pre.next = next;
node.prev = null;
}
if(next == null){
tail = pre;
}else{
next.prev = pre;
node.next = null;
}
size--;
}
}