单链表
概念:单链表就是一个结点存放元素的值和指向下一个结点的引用!分为带头结点和非带头结点
单链表要实现插、删、查、改!
插和删除都需要修改存放在结点的引用地址值,根据链表的数据结构可以知道查和改是需要遍历的!
public class SingleLinkedList {
private int size=0;//有效结点个数,不包括头结点
private int loc=0;
private HeroNode begainnode= new HeroNode(-1,"");
public SingleLinkedList() {
size=0;
loc=0;
}
//在末尾插入元素
public void addlast(HeroNode hero) {
HeroNode temp=begainnode;
while(true) {
if(temp.nextnode==null) {
break;
}
temp=temp.nextnode;
}
//循环用于获取最后位置的结点
temp.nextnode=hero;//这种思路更好,代码块之间耦合更低
size++;
}
//在指定位置插入,(在指定位置后面插入更简单)
public void addlocation(int l, HeroNode hero) {
int s = 0;
if (l + 1 > size) {
System.out.println("没有这个位置");
return;
} else {
HeroNode temphero = getHeroNode(l - 1);// 这个位置的前一个结点
HeroNode t=temphero.nextnode;
temphero.nextnode = hero;
hero.nextnode=t;
size++;
}
}
//获取下标为l的结点,从0开始
public HeroNode getHeroNode(int l) {
int s=-1;
HeroNode temphero=begainnode;
while (true) {
if(s>=size||l==s) {
break;
}
temphero = temphero.nextnode;
s++;
}
return temphero;
}
//删除下标为location的结点
public HeroNode del(int location) {
if(location>size-1) {
System.out.println("删除错误");
return null;
}else {
HeroNode temphero = getHeroNode(location - 1);
HeroNode h=temphero.nextnode;
temphero.nextnode=temphero.nextnode.nextnode;
size--;
return h;
}
}
//删除尾结点
public HeroNode dellast(){
HeroNode temp=del(size-1);
return temp;
}
//列出全部元素
public void listall() {
HeroNode hero=begainnode;
for(int i=0;i<size;i++) {
hero=hero.nextnode;
System.out.println(hero);
}
}
//测试代码
public static void main(String[] args) {
// TODO Auto-generated method stub
SingleLinkedList sll=new SingleLinkedList();
for(int i=0;i<5;i++) {
HeroNode h=new HeroNode(i,"hero"+i);
sll.addlast(h);
}
HeroNode h=new HeroNode(8,"herox");
sll.addlocation(1, h);
sll.listall();
System.out.println("");
sll.del(0);
sll.listall();
}
}
class HeroNode{
public int numb;
public String name;
public HeroNode nextnode;
public HeroNode(int n,String s) {
this.numb=n;
this.name=s;
this.nextnode=null;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "英雄\t"+numb+"\t"+name+"\t";
}
}
双链表
带head结点的双链表就是结点有上一个结点和下一个结点的引用值!
/*
* 和单边二叉树有点像
*/
public class MyLinkedList<AnyType> implements Iterator<AnyType> {
private Node<AnyType> beginMarker;
private Node<AnyType> endMarker;
private int modCount=0;
private int theSize;
//初始化
public MyLinkedList() {
doclear();
}
private void doclear() {
beginMarker=new Node<AnyType>(null,null,null);
endMarker=new Node<AnyType>(null,beginMarker,null);
beginMarker.next=endMarker;
modCount++;
theSize=0;
}
//重新初始化文件
public void clear() {
doclear();
}
public void addBefore(Node<AnyType> p,AnyType x) {
//这就创建一个新的节点
Node<AnyType> newnode=new Node<AnyType>(x,p.prev,p);
p.prev.next=newnode;
p.prev=newnode;
theSize++;
modCount++;
}
public int size() {
return theSize;
}
public boolean add(AnyType x) {
add(size(),x);
return true;
}
private void add(int index, AnyType x) {
// TODO Auto-generated method stub
addBefore(getNode(index,0,size()),x);
}
public AnyType remove(int index) {
return remove(getNode(index));
}
public AnyType get(int index) {
return getNode(index).data;
}
//删除节点,并返回删除节点的值
public AnyType remove(Node<AnyType> node) {
node.next.prev=node.prev;
node.prev.next=node.next;
theSize--;
modCount++;
return node.data;
}
private Node<AnyType> getNode(int index) {
return getNode(index,0,size()-1);
}
public Node<AnyType> getNode(int index,int lower,int upper) {
Node<AnyType> p;
if(index<lower||index>upper) {
throw new IndexOutOfBoundsException();
}
if(index<size()/2) {
p=beginMarker.next;
for(int i=0;i<index;i++) {
p=p.next;
}
}else {
p=endMarker;
for(int i=size();i>index;i--) {
p=p.prev;
}
}
return p;
}
public java.util.Iterator<AnyType> iterator(){
return new LinkedListIterator();
}
private class LinkedListIterator implements java.util.Iterator<AnyType>{
private Node<AnyType> currentnode=beginMarker.next;
private int modcount=modCount;
private boolean okToRemove=false;
@Override
public boolean hasNext() {
return currentnode!=endMarker;
}
@Override
public AnyType next() {
if(modCount!=modcount) {
throw new java.util.ConcurrentModificationException();
}
if(!hasNext()) {
throw new java.util.NoSuchElementException();
}
AnyType item=currentnode.data;
currentnode=currentnode.next;
okToRemove=true;
return item;
}
public void remove() {
if(modCount!=modcount) {
throw new java.util.ConcurrentModificationException();
}
if(!okToRemove) {
throw new IllegalStateException();
}
MyLinkedList.this.remove(currentnode.prev);
modcount++;
okToRemove=false;
}
}
@Override
public boolean hasNext() {
// TODO Auto-generated method stub
return false;
}
@Override
public AnyType next() {
// TODO Auto-generated method stub
return null;
}
//每一个节点的信息
private static class Node<AnyType>{
public Node(AnyType d,Node<AnyType> p,Node<AnyType> n) {
data=d;
prev=p;
next=n;
}
private AnyType data;
public Node<AnyType> prev;
public Node<AnyType> next;
}
}
单向环形(循环)链表
丢手绢、约瑟夫问题:编号为1、2、到n的n个人,约定第k个人从1开始报数,数到m的那个人出列,下一个人从1开始开始数数,依次类推,知道全部出列,给出出列顺序!
这个一个循环报数的问题,并且相邻的编号之前是有前后关系的,这里面还涉及删除操作,是可以用环形链表来实现这个问题。(三种实现方式)
package sparesearray;
import java.util.ArrayList;
/*
* SingleLinkedList of no headnode
*/
public class Josephus {
Joheronode begainnode;
int n;
int k;
int m;
public ArrayList<Joheronode> list=new ArrayList<>();
//
public Josephus(int size,int k,int m) {
this.n=size;
this.k=k;
this.m=m;
init(size);//让一定数量的对象形成循环链表的关系,只有知道其中一个对象,就可以列出所有对象
setbegainnode(k);
listinit();
removeall(m);
}
//不带头结点,初始化
public void init(int size) {
begainnode =new Joheronode(1);
Joheronode j=begainnode;
Joheronode temp;
for(int i=2;i<=size-1;i++) {
temp=new Joheronode(i);
j.nextnode=temp;
j=temp;
}
temp=new Joheronode(size);
j.nextnode=temp;
temp.nextnode=begainnode;
}
//列出初始值
public void listinit() {
Joheronode temp=begainnode;
for(int i=1;i<=n;i++) {
System.out.println(temp);
temp=temp.nextnode;
}
}
//先获取第k个结点
public Joheronode getlocnode(int k) {
Joheronode temp=begainnode;
for(int i=2;i<=k;i++) {
temp=temp.nextnode;
}
return temp;
}
//让第k个结点为初始结点
public void setbegainnode(int k) {
Joheronode temp=begainnode;
for(int i=2;i<=k;i++) {
temp=temp.nextnode;
}
begainnode=temp;
}
//删除第m个结点,m大于等于1
public Joheronode remove(int m) {
Joheronode temp=begainnode;
Joheronode t;
int k=m%n;
if(n==1) {
list.add(begainnode);
} else {
// if (k == 0) {
// t = getlocnode(n - 1);
// temp = t.nextnode;
// begainnode = temp.nextnode;
// t.nextnode = t.nextnode.nextnode;
//
// } else if (k == 1) {
// t = getlocnode(n);
// temp = t.nextnode;
// begainnode = temp.nextnode;
// t.nextnode = t.nextnode.nextnode;
// } else {
// t = getlocnode(k - 1);
// temp = t.nextnode;
// begainnode = temp.nextnode;
// t.nextnode = t.nextnode.nextnode;
// }
t = getlocnode(k==1?n:(n+k-1)%n);
temp = t.nextnode;
begainnode = temp.nextnode;
t.nextnode = t.nextnode.nextnode;
list.add(temp);
}
n--;
return temp;
}
public void removeall(int m) {
while(n>0) {
remove(m);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Josephus j=new Josephus(5,2,2);
System.out.println("删除");
// for(int i=1;i<6;i++) {
// j.remove(2);
// }
System.out.println(j.list);
}
}
class Joheronode{
private int number;
public Joheronode nextnode;
public Joheronode(int n) {
this.number=n;
}
@Override
public String toString() {
return "hero "+number+"\t";
}
}