目录
双向链表
单链表指针域存放下一个结点的地址,双向链表有两个指针域,一个指针域存放前一个结点的地址,一个指针域存放下一个结点的地址
不带有头结点的双向链表的操作
打印元素
正向打印
public void printFront(){
LinkNode p=head;
while(p!=null){
System.out.print(p.val+" ");
p=p.next;
}
System.out.println();
}
倒叙打印
public void printTail(){
LinkNode p=tail;
while(p!=null){
System.out.print(p.val+" ");
p=p.prev;
}
System.out.println();
}
链表长度
public int getLength() {
int count = 0;
LinkNode p = head;
while (p != null) {
count++;
p = p.next;
}
return count;
}
插入元素
头插法
如果插入之前为空,那么head,tail指向新的结点,那么新建的链表如图:
插入之前不为空时,如下更改
public void pushFront(int data){
LinkNode newnode= new LinkNode(data);
if(head==null){
tail=head=newnode;
return ;
}
head.prev=newnode;
newnode.next=head;
newnode.prev=null;
head=newnode;
}
尾插法
如果插入之前为空,head,tail指向新的结点,那么新建的链表如图:
public void pushTail(int data){
LinkNode newnode= new LinkNode(data);
if(tail==null){
tail= head=newnode;
return ;
}
tail.next=newnode;
newnode.prev=tail;
// newnode.next=null;//成员变量,默认赋值null
tail=newnode;
}
在任意位置插入元素
public void pushInsert(int pos, int data) {
if (pos < 0 || pos > getLength()) {//
System.out.println("插入位置不合法");
return;
}
LinkNode newnode = new LinkNode(data);
if (head == null) {//插入之前空
head = tail = newnode;
return;
}
if (pos == 0) {
pushFront(data);
return;
}
if (pos == getLength()) {
pushTail(data);
return;
}
LinkNode p = head;
while (p != null && pos-- > 0) {
p = p.next;//得到插入位置
}
if (p == null) return;
newnode.next = p.prev.next;//新节点的后指针域存放上一个结点后指针域的值
newnode.prev = p.prev;//新节点的前指针域存放上一个结点的地址
p.prev.next = newnode;//前一个结点的后指针域指向新节点
p.prev = newnode;//新节点的后一个结点的前指针域指向这个新节点
}
删除元素
删除第一个结点
public void deleateFront(){
if(head==null || head.next==head.prev&&head.prev==null){//只有0个或者一个结点
head=tail=null;
return ;
}
head.next.prev=null;
head=head.next;
}
删除最后一个结点
public void deleateTail(){
if(head==null || head.next==head.prev&&head.prev==null){//只有0个或者一个结点
head=tail=null;
return ;
}
tail.prev.next=null;
tail=tail.prev;
}
删除某一个下标的元素
public void deleateInsert( int pos){
if (pos < 0 || pos >= getLength()) {
System.out.println("删除位置不合法");
return;
}
if (head == null || head.next == head.prev && head.prev == null) {//只有0个或者一个结点
head = tail = null;
return;
}
if (pos == 0) {
head.next.prev = null;//head.next==null的情况
head = head.next;
return;
}
LinkNode p = head;
while (p != null && pos-- > 0) {
p = p.next;//得到插入位置
}
if(p==null) return ;
if (p.next == null) {//删除位置在末尾
p.prev.next = p.next;//p.prev==null---删除头结点
tail = tail.prev;
}
if (p.next != null) {
p.prev.next=p.next;//p.prev==null---删除头结点
p.next.prev=p.prev;//p.next==null---删除尾结点
}
}
删除第一次数据域等于val的结点
public void deleateOnce(int data) {
if (head == null) {
return;
}
LinkNode p = head;//p指向删除结点
while (p!=null){
if(p.val==data){
if(p==head){//删除第一个结点的情况单独处理,分为两种情况
if(head.next==null){//只有一个结点
tail=head=null;
return ;
}
head.next.prev=null;
head=head.next;
return ;
}
if(p.next==null){//删除位置在末尾,尾指针更改
tail.prev.next=null;
tail=tail.prev;
return ;
}
p.prev.next=p.next;
p.next.prev=p.prev;
return;
}
p=p.next;
}
}
删除所有数据域等于val的结点
public void deleateTimes(int data) {
if (head == null) {
return;
}
LinkNode p = head;//p指向删除结点
while (p != null) {
if (p.val == data) {
if (p == head) {//删除第一个结点的情况单独处理,分为两种情况
if (head.next == null) {//只有一个结点
tail = head = null;
return;
}
head.next.prev = null;
head = head.next;
} else if (p.next == null) {//删除位置在末尾,尾指针更改
tail.prev.next = null;
tail = tail.prev;
return;
} else {
p.prev.next = p.next;
p.next.prev = p.prev;
}
}
p = p.next;
}
}