线性表
线性表就是最普通意义上的按一定顺序排列的某一元素的集合,就是普通的 arrayList LinnkedList等类似的有序集合,存在下标,同时线性表又包含两种实现。
一种是 :数组类的实现
另一种是:链表类的实现
数组实现
数组实现在代码里体现的话一般是类似于如下样子:
表示一个容量为 3 的有序数组
int[] array = new int[3];
特点:数组里的元素是连续存储的,且数组的大小一旦固定后就无法改变如果要改变容量,那么就意味着需要重新创建一个新的数组来容纳数据。
假设我创建一个容量为3的数组,那么对应下标分别是0, 1, 2;
然后我要将这个数组存储到另一个数组中那么,示例代码如下(仅供参考)
public class LineTable {
private static int[] oldArray = new int[3];
private static int[] newArray = new int[5];
// 静态代码块赋值
static {
System.out.println("static code block execute start..........");
oldArray[0] = 1;
oldArray[1] = 2;
oldArray[2] = 3;
System.out.println("static code block execute end..........");
}
public static void main(String[] args) {
System.out.println("main thread start----------");
copyToNew(oldArray, newArray);
System.out.println("main thread end----------");
}
/**
*copy 数据
* @param oldArray
* @param newArray
*/
private static int[] copyToNew(int[] oldArray, int[] newArray){
for (int i=0; i < oldArray.length; i++){
newArray[i] = oldArray[i];
}
oldArray = newArray;
return oldArray;
}
}
获取某一下标的数值是很容易的但是如果在数组中间添加某一数值时,在指定位置添加数值后,排在后面的数据将需要依次向后移动。数量越多花费的时间越多。
在某一指定的位置添加指定内容可以参考以下代码:
public class LineTable {
private static int[] oldArray = new int[3];
private static int[] newArray = new int[5];
static {
System.out.println("static code block execute start..........");
oldArray[0] = 1;
oldArray[1] = 2;
oldArray[2] = 3;
System.out.println("static code block execute end..........");
}
{
System.out.println("code block execute start..........");
System.out.println("code block execute end..........");
}
public static void main(String[] args) {
System.out.println("main thread start----------");
// copyToNew(oldArray, newArray);
int[] ints = addElement(oldArray, 5, 4);
foreachArray(ints );
System.out.println("main thread end----------");
}
/**
*copy 数据
* @param oldArray
* @param newArray
*/
private static int[] copyToNew(int[] oldArray, int[] newArray){
for (int i=0; i < oldArray.length; i++){
newArray[i] = oldArray[i];
}
oldArray = newArray;
return oldArray;
}
/**
* 线性表添加元素
* @param srcArray
* @param index
* @param intElement
*/
private static int[] addElement(int[] srcArray, int index, int intElement){
if (index < 0){
System.out.println("out of right index Exception");
return null;
}
// 未过界 添加一 添加位置均后移一位
if (index <= srcArray.length){
int[] newarray = new int[srcArray.length+1];
int[] ints = copyToNew(srcArray, newarray);
// 后移
for (int i = ints.length-1; i > index; i--){
ints[i] = ints[i-1];
}
ints[index] = intElement;
return ints;
}else{
// 过界
int size = index+1;
int[] newArray = new int[size];
int[] ints = copyToNew(srcArray, newArray);
ints[index] = intElement;
return ints;
}
}
/**
* 线性遍历打印
* @param array
*/
private static void foreachArray(int[] array){
for (int i : array) {
System.out.print(i+" ");
System.out.println();
}
}
}
链表
链表的存储方式为每一个节点上都会存储当前的存储的内容以及这个节点的下一个节点的信息(双向链表也会保存上一个节点的信息)。
这里以单链表为例简单展示,实际上还有双向链表和循环链表等。
与数组不同的是链表的存储并不是连续的,可以通过指向不同的地址来连接下一个元素,这样如果需要删除或者增加时,只需要改变节点的指向既可,改动很小,具体参考代码如下:
首先创建链表的节点类
这个节点类相当于存放一些实际的数据,就我看来实际使用时可以放入Object,我的自定的类,里面的内容可以很多,然后同时保存下一个节点类在这个母类里面,最终相当于套娃一类的东西,不断叠加下去。
/**
* 单向链表 节点
* @param <E> 这里的E其实就是类的泛型 这里采用了element元素缩写e 对数据类型的要求 新建时也可以不写入泛型
*/
public class Node<E> {
E element;
Node<E> next;
public Node(E element, Node<E> next) {
this.element = element;
this.next = next;
}
public Node(E element) {
this.element = element;
this.next = null;
}
}
然后再写主要测试
如下:
/**
* 链表
*/
public class LinkedTable {
public static void main(String[] args) {
// 创建首尾节点
Node head = null;
Node tail = null;
// 创建节点并赋初值
head = new Node("nodedata1");
tail = head;
// 指向下一个节点
tail.next = new Node("nodedata2");
tail = tail.next;
// 遍历节点
Node<String> current = head;
while (current != null){
System.out.println(current.element);
current = current.next;
}
}
/**
* 倒叙遍历当前节点
* @param currentNode
*/
private static void printReversList(Node<String> currentNode){
if (currentNode != null){
// 递归调用 直到最后时也就成了倒序输出
printReversList(currentNode.next);
System.out.println(currentNode.element);
}
}
/**
* 单链表反转 注意改变两个节点之间的指向关系
* @return
*/
private static Node<String> ReverseLinkedList(Node<String> start){
if (start == null){
return null;
}
Node<String> resultNode = null;
Node<String> NodeRe = null;
Node<String> currentNode = start;
while (currentNode != null){
Node<String> next = currentNode.next;
if (next != null){
resultNode = currentNode;
}
currentNode.next = NodeRe;
NodeRe = currentNode;
currentNode = next;
}
return resultNode;
}
}
main中或写为
// 创建首尾节点
Node head = null;
Node tail = null;
// 创建节点并赋初值
head = new Node("node1");
// 指向下一个节点
tail = new Node("node2");
head.next = tail;
// 遍历节点
Node<String> current = head;
while (current != null){
System.out.println(current.element);
current = current.next;
}