无向单链表的实现
定义一个类Node,表示链表的节点
class Node{
public int date;
public Node next;
public Node(int date){
this.date=date;
}
构造链表
public class MyList {
public Node head = null;
1.使用头插法插入节点
public void addFirst(int date) {
Node node= new Node(date);
node.next = this.head;
this.head = node;
}
2.使用尾插法插入节点
public void addLast(int date) {
Node node = new Node(date);
Node node2 = this.head;
//这里需要判断头节点是否为空
if (this.head == null) {
this.head = node;
}
while (node2.next != null) {
node2 = node2.next;
}
node2.next = node;
}
3.任意位置插入
public boolean addIndex(int index,int date){
if (index<0||index>size()){
System.out.println("index不合法");
return false;
}
//第一个节点用头插法
if (index==0){
addFirst(date);
return true;
}
//最后一个节点用尾插法
if (index==size()){
addLast(date);
return true;
}
//在中间
Node node=new Node(date);
node.next=prev(index).next;
prev(index).next=node;
return true;
}
二、基本方法的实现
1.遍历节点进行打印
public void show() {
Node node = this.head;
while (node != null) {
System.out.print(node.date + " ");
node = node.next;
}
System.out.println();
System.out.println("==========================");
}
2.从指定结点开始打印
public void show2(Node newHead){
Node node=newHead;
while(node!=null){
System.out.print(node.date + " ");
node = node.next;
}
System.out.println();
System.out.println("==========================");
3.找第n-个节点位置
public Node prev(int index){
Node node=this.head;
while(index-1-1!=0){
node=node.next;
index--;
}
return node;
}
4.求链表长度
public int size(){
int count=0;
if (this.head==null){
return 0;
}
Node node=this.head;
while (node!=null){
count++;
node=node.next;
}
return count;
}
5.查找是否有关键字key
public boolean contains(int key){
Node node=this.head;
while(node!=null){
if (node.date==key){
return true;
}
node=node.next;
}return false;
}
6.删除关键字key
这里需要先找到key节点的前置节点,用到了另外一个方法
public void remove(int key){
Node node=this.head;
if (this.head.date==key){
this.head=this.head.next;
return;
}
Node cur=keyWard(key);
if (cur==null){
return;
}
cur.next=cur.next.next;
7.找key的前置节点
public Node keyWard(int key){
Node node=this.head;
while(node.next!=null){
if (node.next.date==key){
return node;
}node=node.next;
}return null;
}
8.删除所有key
public void removeAkey(int key){
Node prev=this.head;
Node cur=this.head.next;
while(cur!=null){
if (cur.date==key){
prev.next=cur.next;
cur=cur.next;
}else if (cur.date!=key){
prev=prev.next;
cur=cur.next;
}
if (this.head.date==key){
this.head=this.head.next;
}
}
}
9.反转链表
这里用两种方法
A.
遍历链表,将头节点的下一个节点置为新的头节点
public Node reverList(){
if (this.head==null){
return null;
}
Node cur=this.head;
Node curNest=this.head.next;
cur.next=null;
cur=curNest;
while (cur != null) {
curNest=cur.next;
cur.next=this.head;
this.head=cur;
cur=curNest;
}
return this.head;
}
B.
构造一个傀儡节点,遍历链表将所有的节点置于傀儡节点之前
public Node reverList2() {
Node prev = null;
Node cur = this.head;
Node newHead=null;
while(cur!=null){
Node curNext=cur.next;
if (curNext==null){
newHead=cur;
}
cur.next=prev;
prev=cur;
cur=curNext;
}
return newHead;
10.求中间节点
如果有两个中间节点,则返回第二个
快慢指针法
public int middle(){
Node fast=this.head;
Node slow=this.head;
while(fast!=null&&fast.next!=null){
fast=fast.next.next;
slow=slow.next;
}
return slow.date;
}
11.将所有小于x的值放于其余值之前
public Node daXiao(int k){
Node bs=null;
Node be=null;
Node as=null;
Node ae=null;
Node cur=this.head;
while(cur!=null){
if (cur.date<k){
if (bs==null) {
bs = cur;
be = cur;
}else{
be.next=cur;
be=be.next;
}
}else{
if (as==null){
as=cur;
ae=cur;
}else{
ae.next=cur;
ae=ae.next;
}
}cur=cur.next;
}
if (bs==null){
return as;
}
be.next=as;
if (as!=null){
ae.next=null;
}
return bs;
}
12.删除所有重复节点
public Node removeDuo(){
Node tmpHead=new Node(-1);//定义一个傀儡节点用来链接链表
Node cur=this.head;
Node node= tmpHead;
while(cur!=null){//只有一个节点的情况和正常情况
if(cur.next!=null&&cur.date==cur.next.date){
while(cur.next!=null&&cur.date==cur.next.date){
cur=cur.next;
}cur=cur.next;
}else{
tmpHead.next=cur;
tmpHead=tmpHead.next;
cur=cur.next;
}
tmpHead.next=null;
}
return node.next;
}
13.判断是否为回文结构
public boolean huiWen(){
if (this.head==null) {
return false;}
if (this.head.next==null){
return true;
}
Node fast=this.head;
Node slow=this.head;
while(fast!=null&&fast.next!=null){
fast=fast.next.next;
slow=slow.next;
}
//slow是中间节点
Node cur=slow.next;
while(cur!=null){
Node curNext=cur.next;
cur.next=slow;
slow=cur;
cur=curNext;
}
while(this.head!=slow){
if (slow.date!=this.head.date){
return false;
}if (this.head.next==slow){
return true;
}slow=slow.next;
this.head=this.head.next;
}
return true;
}
14.判断一个链表是否成环链表
public boolean hasCrcle(){
Node slow=this.head;
Node fast=this.head;
while(fast.next!=null&&fast!=null){
slow=slow.next;
fast=fast.next.next;
if (slow==fast){
return true;
}
}return false;
}
15.找到环链表的入环点
public Node searchNodecircle(){
Node fast=this.head;
Node slow=this.head;
while (fast.next!=null&&fast!=null){
fast=fast.next.next;
slow=slow.next;
if(fast==slow) {
break;
}
}if (fast.next==null||fast==null){
return null;
}
slow=this.head;
while(fast!=slow){
slow=slow.next;
fast=fast.next;
}
return slow;
}
16.输出倒数第k个节点
public Node 倒数k节点(int k){
if (k<=0||k>this.size()){
System.out.println("k值不合法");
return null;
}
Node node=this.head;
int count=this.size()-k;
while(count!=0){
node=node.next;
count--;
}
return node;
}