链表与数组的区别
数组队列的实现原理是:创建一个数组时,都会开辟新的内存空间,让数组名存储这块
内存的首地址;
链表的实现原理是:借助于对象名中存储的是地址。
链表:存储空间不是连续的
每一个节点都会存储一个指向下一个节点的引用(地址)
每一个节点还会存储数据。
单链表,双链表,循环链表
单链表:单向指向
双链表:双向指向
循环链表:双向指向,头尾连在一起
链表的实现步骤:
定义一个节点类,再之后定义链表类,主函数类(测试)
节点类:
//节点类
public class Node {
//声明数据域,节点内的数据对象
private Object obj;
//对下一个节点的引用
private Node child;
//对上一个节点的引用
private Node parent;
//构造方法
public Node( Object obj){
this.obj=obj;
}
外加各种set()方法,get()方法
//重写toString方法,变为字符串输出
public String toString(){
return obj+"" ;
}
}
链表类(双链表)
public class LinkedList<E> {
//根节点
private Node root;
//尾节点
private Node endnode;
//个数
private int size;
public LinkedList(){
}
//添加节点,是添加到尾节点之后
public void add(E obj){
//创建一个新的节点node
Node node = new Node(obj);
//如果链表为空,则加入的节点就是根节点,尾节点指向根节点
if(root==null){
root=node;
endnode=node;
}else{
//将新节点设置为尾节点的下一个节点
endnode.setChild(node);
//将新节点的父节点设为原先的尾节点
node.setParent(endnode);
//将尾节点移动到新添加的节点上,此处表示是末尾节点。
endnode=node;
}
size++;
}
//移除指定索引位置的数据
public E remove(int index){
Node node=root;//循环的节点
Node removeNode;//要移除的节点
//如果移除的是第一个节点
if(index==0){
root=node.getChild();//将root的下一个节点设置为root
if(root!=null)
root.setParent(null);//root的下一个节点的父节点设置为null
removeNode=node;//把原来的root赋给要移除的节点,因为之后要返回移除的节点
}
else{
for(int i=0;i<index;i++)
//node最开始初始设为根节点,因为链表是要从根节点开始访问,一个接一个才能访问到下标为index的位置
node=node.getChild();
//判断要移除的节点是否是最后一个
if(index==size-1){
//将node的下一个节点赋给移除的节点
removeNode=node;
//将node的子节点设置为null,把尾节点的子节点设为null
Node parent = node.getParent();
parent.setChild(null);
endnode = parent;
}else {//要移除的节点是在链表的中间
//将node的下一个节点赋给要移除的节点
removeNode=node;
//将removeNode下一个节点的引用赋给childNode
Node childNode=removeNode.getChild();
Node parentNode = removeNode.getParent();
//将chidNode赋给node,保持链表不断
parentNode.setChild(childNode);
childNode.setParent(parentNode);
}
}
size--;
return (E)removeNode.getObj();
}
//获取指定索引位置节点的数据
public E get(int index){
if(index<0||index>=size)
return null;
Node node=root;
//循环获取到指定索引位置的数据
for(int i=0;i<index;i++){
node=node.getChild();
}
return (E)node.getObj();
}
//修改指定位置节点的数据
public void modeify(Object obj,int index){
Node node1=root;
for(int i=0;i<index;i++){
node1=node1.getChild();
}
node1.setObj(obj);
}
//返回节点总数
public int size(){
return size;
}
}
测试类:
public class LinkedTest {
public static void main(String[] args) {
LinkedList<Object> ll = new LinkedList<Object>();
Random rand = new Random();
int temp;
// 循环创建节点添加到链表中
for (int i = 0; i < 10; i++) {
Node node = new Node(rand.nextInt(50));
ll.add(node);
System.out.print(ll.get(i) + " ");
}
for (int i = ll.size()-1; i >0; --i) {
for (int j = 0; j < i; ++j) {
//可以把Object型转为int型,可以强制转换加Integer
String str1 = String.valueOf(ll.get(j));
int n = Integer.parseInt(str1);
String str = String.valueOf(ll.get(j+1));
int m = Integer.parseInt(str);
if (m<n) {
temp = n;
ll.modeify(m, j);
ll.modeify(temp, j+1);
}
}
}
for (int g = 0; g < ll.size(); g++) {
System.out.print(ll.get(g) + " ");
}
}
}
之后要用链表队列,做界面排序,但是目前只有排序做好了,显示在界面上还有待计算。
数组队列的实现原理是:创建一个数组时,都会开辟新的内存空间,让数组名存储这块
内存的首地址;
链表的实现原理是:借助于对象名中存储的是地址。
链表:存储空间不是连续的
每一个节点都会存储一个指向下一个节点的引用(地址)
每一个节点还会存储数据。
单链表,双链表,循环链表
单链表:单向指向
双链表:双向指向
循环链表:双向指向,头尾连在一起
链表的实现步骤:
定义一个节点类,再之后定义链表类,主函数类(测试)
节点类:
//节点类
public class Node {
//声明数据域,节点内的数据对象
private Object obj;
//对下一个节点的引用
private Node child;
//对上一个节点的引用
private Node parent;
//构造方法
public Node( Object obj){
this.obj=obj;
}
外加各种set()方法,get()方法
//重写toString方法,变为字符串输出
public String toString(){
return obj+"" ;
}
}
链表类(双链表)
public class LinkedList<E> {
//根节点
private Node root;
//尾节点
private Node endnode;
//个数
private int size;
public LinkedList(){
}
//添加节点,是添加到尾节点之后
public void add(E obj){
//创建一个新的节点node
Node node = new Node(obj);
//如果链表为空,则加入的节点就是根节点,尾节点指向根节点
if(root==null){
root=node;
endnode=node;
}else{
//将新节点设置为尾节点的下一个节点
endnode.setChild(node);
//将新节点的父节点设为原先的尾节点
node.setParent(endnode);
//将尾节点移动到新添加的节点上,此处表示是末尾节点。
endnode=node;
}
size++;
}
//移除指定索引位置的数据
public E remove(int index){
Node node=root;//循环的节点
Node removeNode;//要移除的节点
//如果移除的是第一个节点
if(index==0){
root=node.getChild();//将root的下一个节点设置为root
if(root!=null)
root.setParent(null);//root的下一个节点的父节点设置为null
removeNode=node;//把原来的root赋给要移除的节点,因为之后要返回移除的节点
}
else{
for(int i=0;i<index;i++)
//node最开始初始设为根节点,因为链表是要从根节点开始访问,一个接一个才能访问到下标为index的位置
node=node.getChild();
//判断要移除的节点是否是最后一个
if(index==size-1){
//将node的下一个节点赋给移除的节点
removeNode=node;
//将node的子节点设置为null,把尾节点的子节点设为null
Node parent = node.getParent();
parent.setChild(null);
endnode = parent;
}else {//要移除的节点是在链表的中间
//将node的下一个节点赋给要移除的节点
removeNode=node;
//将removeNode下一个节点的引用赋给childNode
Node childNode=removeNode.getChild();
Node parentNode = removeNode.getParent();
//将chidNode赋给node,保持链表不断
parentNode.setChild(childNode);
childNode.setParent(parentNode);
}
}
size--;
return (E)removeNode.getObj();
}
//获取指定索引位置节点的数据
public E get(int index){
if(index<0||index>=size)
return null;
Node node=root;
//循环获取到指定索引位置的数据
for(int i=0;i<index;i++){
node=node.getChild();
}
return (E)node.getObj();
}
//修改指定位置节点的数据
public void modeify(Object obj,int index){
Node node1=root;
for(int i=0;i<index;i++){
node1=node1.getChild();
}
node1.setObj(obj);
}
//返回节点总数
public int size(){
return size;
}
}
测试类:
public class LinkedTest {
public static void main(String[] args) {
LinkedList<Object> ll = new LinkedList<Object>();
Random rand = new Random();
int temp;
// 循环创建节点添加到链表中
for (int i = 0; i < 10; i++) {
Node node = new Node(rand.nextInt(50));
ll.add(node);
System.out.print(ll.get(i) + " ");
}
for (int i = ll.size()-1; i >0; --i) {
for (int j = 0; j < i; ++j) {
//可以把Object型转为int型,可以强制转换加Integer
String str1 = String.valueOf(ll.get(j));
int n = Integer.parseInt(str1);
String str = String.valueOf(ll.get(j+1));
int m = Integer.parseInt(str);
if (m<n) {
temp = n;
ll.modeify(m, j);
ll.modeify(temp, j+1);
}
}
}
for (int g = 0; g < ll.size(); g++) {
System.out.print(ll.get(g) + " ");
}
}
}
之后要用链表队列,做界面排序,但是目前只有排序做好了,显示在界面上还有待计算。