数据结构基础(一)线性表
2015-12-20 19:44
381 查看
大学快要结束了,打算抓紧最后一段时间回顾下数据结构的知识,今天是第一篇,希望自己能够坚持完。
定义
线性表是n个数据元素的有限序列。线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的。
分类
顺序表:即用数组实现的线性表。逻辑上相邻的元素物理地址也相邻,访问容易,插入和删除元素麻烦
链表:用指针连接元素,逻辑上相邻的元素物理地址不一定相邻。访问麻烦,插入和删除容易。
又可分为:
线性链表:除终节点外,每个节点都有指向下一个元素的指针
循环链表:最后一个节点指向头节点
双向链表:每个节点都有指向前个节点和后个节点的指针
Demo
顺序表Demo
单链表Demo
双向链表和双向循环链表就不举例了,只是在单链表的基础上Node加了一些改动。实际上java的LinkedList里面采用的就说双向链表。
定义
线性表是n个数据元素的有限序列。线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的。
分类
顺序表:即用数组实现的线性表。逻辑上相邻的元素物理地址也相邻,访问容易,插入和删除元素麻烦
链表:用指针连接元素,逻辑上相邻的元素物理地址不一定相邻。访问麻烦,插入和删除容易。
又可分为:
线性链表:除终节点外,每个节点都有指向下一个元素的指针
循环链表:最后一个节点指向头节点
双向链表:每个节点都有指向前个节点和后个节点的指针
Demo
顺序表Demo
//模仿ArrayList的顺序表 public class Arraylist { private Object[] elementDate=null; private int capacity; private int current; //默认初始化容器大小为5 public Arraylist(){ this.current=0; this.capacity=5; this.elementDate=new Object[capacity]; } //按所给容量初始化容器 public Arraylist(int capacity){ this.current=0; this.capacity=capacity; this.elementDate=new Object[capacity]; } //获得指定索引的元素 public Object get(int index) { if(index>=0&&index<capacity) return elementDate[index]; return null; } //添加元素 public void add(Object element) { //每次插入都要检查容器大小 ensureCapacity(); elementDate[current++]=element; } //在指定下标插入元素 public void add(int index,Object element) { //每次插入都要检查容器大小 ensureCapacity(); //确定下标合法 if(index>current||index<0) throw new IndexOutOfBoundsException(); for (int i = current; i >index; i--) { elementDate[i]=elementDate[i-1]; } elementDate[index]=element; current++; } //删除指定位置的元素 public void delete(int index) { if(index>=current||index<0) throw new IndexOutOfBoundsException(); // //也可直接使用函数复制数组 // int length=current-index; // System.arraycopy(elementDate, index+1, elementDate, index, length); for (int i = index; i < current-1; i++) { elementDate[i]=elementDate[i+1]; } elementDate[--current]=null; } //确保增加元素后的容器不会溢出 public void ensureCapacity() { if(current+1>=capacity){ capacity+=5; Object[] newElementDate=new Object[capacity]; // elementDate=Arrays.copyOf(elementDate, capacity); //也直接使用函数 for (int i = 0; i < elementDate.length; i++) { newElementDate[i]=elementDate[i]; } elementDate=newElementDate; } } //遍历出容器内的元素 public void dolist() { for (int i = 0; i < current; i++) { System.out.print(elementDate[i]+" "); } System.out.println("["+capacity+"]"); } public static void main(String[] args) { Arraylist list=new Arraylist(); System.out.println("添加4个元素"); list.add(1); list.add(2); list.add(3); list.add(4); list.dolist(); System.out.println("插入一个元素"); list.add(1, 1.5); list.dolist(); System.out.println("删除一个元素"); list.delete(1); list.dolist(); System.out.println("获取指定4位置元素"); System.out.println(list.get(4)); System.out.println("再加几个元素测试溢出"); list.add(5); list.add(6); list.dolist(); } }/*output 添加4个元素 1 2 3 4 [5] 插入一个元素 1 1.5 2 3 4 [10] 删除一个元素 1 2 3 4 [10] 获取指定4位置元素 null 再加几个元素测试溢出 1 2 3 4 5 6 [10]**/
单链表Demo
//模仿LinkedList的单链表 public class Linkedlist { // 链表的第一个节点 private Node first; // 链表的最后一个节点 private Node last; // 链表的长度 private int size = 0; /** * 链表节点 */ private static class Node { // Node pre; //若为双向链表加上,实际LinkedList就是双向链表结构 Object item; Node next; public Node(Object item, Node next) { this.item = item; this.next = next; } } /** * 空构造,第一次添加元素时才初始化first,last */ public Linkedlist() { // TODO Auto-generated constructor stub } /** * 添加一个元素 * * @param element */ public void add(Object element) { Node newNode = new Node(element, null); Node l = last; last = newNode; // 如果此时为空链表,则初始化first,last if (first == null) first = last; else l.next = newNode; size++; } /** * 增加元素到指定的下标位置 * * @param index * @param element */ public void add(int index, Object element) { // 检验索引是否正确 if (index < 0 || index > size) throw new IndexOutOfBoundsException(); // 判断是否插在last节点后 if (index == size) { add(element); } // 判断是否插在first节点上 else if (index == 0) { Node newNode = new Node(element, first); first = newNode; size++; } else { Node preNode = getNode(index - 1); Node nextNode = preNode.next; Node newNode = new Node(element, nextNode); preNode.next = newNode; size++; } } /** * 删除指定索引处的节点元素 * * @param index */ public void delete(int index) { // 检验索引是否正确 if (index < 0 || index >= size) throw new IndexOutOfBoundsException(); // 判断是否删除first节点 if (index == 0) { first = first.next; } else { Node preNode = getNode(index - 1); Node delNode = preNode.next; Node nextNode = delNode.next; preNode.next = nextNode; // 判断是否删除last节点 if (index == size-1) last=preNode; // 方便垃圾回收机制回收 delNode.item = null; delNode.next = null; } size--; } /** * 获取指定下标的节点 * * @param index * @return */ public Node getNode(int index) { // 检验索引是否正确 if (index < 0 || index >= size) throw new IndexOutOfBoundsException(); // 从头节点开始寻找,如果为双向链表,可以判断index挨头和尾哪边近,然后从哪边开始查找 Node node = first; for (int i = 0; i < index; i++) { node = node.next; } return node; } public Object get(int index) { return getNode(index).item; } /** * 遍历输出所有节点元素 */ public void dolist() { Node node = first; for (int i = 0; i < size; i++) { System.out.print(node.item + " "); node = node.next; } System.out.println("[" + size + "]"); } public static void main(String[] args) { Linkedlist list = new Linkedlist(); System.out.println("添加4个元素"); list.add(1); list.add(2); list.add(3); list.add(4); list.dolist(); System.out.println("插入一个元素"); list.add(4, 1.5); list.dolist(); System.out.println("删除一个元素"); list.delete(0); list.dolist(); System.out.println("获取指定3位置元素"); System.out.println(list.get(3)); } }/*output 添加4个元素 1 2 3 4 [4] 插入一个元素 1 2 3 4 1.5 [5] 删除一个元素 2 3 4 1.5 [4] 获取指定3位置元素 1.5**/
双向链表和双向循环链表就不举例了,只是在单链表的基础上Node加了一些改动。实际上java的LinkedList里面采用的就说双向链表。
相关文章推荐
- 数据结构期末总结
- c++ 数据结构 *** 树的部分实现
- 数据结构课期末总结
- 数据结构实验之排序三:bucket sort
- 数据结构实验之排序一:一趟快排
- 数据结构实验之排序二:交换排序
- 代码整洁之道读书笔记--对象和数据结构
- 数据结构-二叉树和二叉查找树
- 数据结构与算法 LeetCode编程练习--Search in Rotated array II
- <LeetCode OJ> 191. Number of 1 Bits
- <LeetCode OJ> 231 / 342 Power of (Two / Four)
- 数据结构上机实验-希尔排序,快速排序,堆排序
- 数据结构小结 说明
- 数据结构小结(九)排序算法大杂烩
- 数据结构小结(八)图的使用
- 数据结构小结(八)图
- 数据结构小结(七)查找
- 数据结构小结(六)树
- 数据结构小结(五) 数组与广义表
- 数据结构小结 (四) 串