您的位置:首页 > 理论基础 > 数据结构算法

数据结构基础(一)线性表

2015-12-20 19:44 381 查看
大学快要结束了,打算抓紧最后一段时间回顾下数据结构的知识,今天是第一篇,希望自己能够坚持完。

定义

线性表是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里面采用的就说双向链表。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: