单链表
-
链表
- head
- 带头节点或不带头节点
- data
- next
- 指向下一个节点
- head
-
创建node类
// 创建node类
public class Node{
public int no;
public String name;
public Node next; //指向下一个节点
public Node(int no,String name){
this.no = no;
this.name = name;
}
// toString
public String toString(){
return "Node [no="+no+",name="+name+"]";
}
}
// 管理链表
public class SingleLinkedList{
// 初始化头
private Node head = new Node(0,"");
// 添加节点
// 不考虑no顺序
// 找到当前链表最后节点
// 最后节点的next指向新节点
public void add(Node node){
Node temp = head;
// 遍历链表
while(true){
// 当next为空
if(temp.next==null){
break;
}
// 如果没有找到最后,将temp后移
temp = temp.next;
}
// 退出循环,temp指向了最后节点
temp.next = node;
}
// 考虑no顺序
public void addByOrder(Node node){
Node temp = head;
boolean flag = false; //添加的编号是否已存在,默认false
while(true){
if(temp.next=null){ // 说明已经是链表的最后
break;
}
if(temp.next.no>node.no){ // 找到位置
break;
}else if(temp.next.no==node.no){// 编号已存在
flag = true;
break;
}
temp = temp.next;
}
// 如果flag=true
if(flag){
System.out.printf("改编号%d已存在\n",node.no);
}else{
node.next = temp.next;
temp.next = node;
}
}
//修改节点,根据no编号修改
public void update(Node node){
// 判断是否为空
if(head.next == null){
System.out.println("链表为空");
return;
}
// 查询需要修改的节点
Node temp = head.next;
boolean flag = false;
while(true){
if(temp==null){
break;
}
if(temp.no == node.no){
flag = true;
break;
}
temp = temp.next;
}
// 根据flag判断是否找到修改的节点
if(flag){
temp.name = node.name;
}else{
// 没有找到
System.out.printf("没有找到编号%d节点\n",node.no);
}
}
// 删除节点
public void del(int no){
Node temp = head;
boolean flag = false;
while(true){
if(temp.next == null){
break;
}
if(temp.next.no == no){
// 该节点下一个节点
flag = true;
break;
}
temp = temp.next;
}
if(flag){
// 删除
temp.next = temp.next.next;
}else{
System.out.printf("没有找到编号%d对应节点",no);
}
}
// 显示链表
public void list(){
if(head.next==null){
System.out.println("链表为空");
return;
}
Node temp = head.next;
while(true){
// 判断是否到链表最后
if(temp ==null){
break;
}
// 打印节点
System.out.println(temp);
// temp后移
temp = temp.next;
}
}
}
- 链表特殊算法
// 获取有效个数
public static int getLength(Node head){
if(head.next==null){
return 0;
}
int length = 0;
Node cur = head.next;
while(cur!=null){
length ++;
cur = cur.next;
}
return length;
}
// 获取倒数第K个节点
public static Node findLastIndexNode(Node head,int index){
if(head.next==null){
return null;
}
int size = getLength(head);
// 遍历
if(index<=0 || index > size){
return null;
}
Node cur = head.next;
for(int i=0;i<size-index;i++){
cur = cur.next;
}
return cur;
}
// 反转节点
public static void reversetList(Node head){
if(head.next==null|| head.next.next == null){
return;
}
Node cur = head.next;
Node next = null; // 指向当前节点下一个节点
Node reverseHead = new Node(0,"");
while(cur!=null){
// 就是将cur插入reverseHead后
// 删除原列表的cur
next = cur.next;
cur.next = reverseHead.next ;
reverseHead.next = cur;
cur = next;
}
head.next = reserseHead.next
}
// 逆序打印
public static void reversePrint(Node head){
if(head.next == null){
return;
}
Stack<Node> stack = new Stack<Node>();
Node cur = head.next();
while(cur != null){
stack.push(cur);
cur = cur.next;
}
// 打印栈中的节点
while(stack.size()>0){
System.out.println(stack.pop());
}
}
双向链表
- 自我删除
public class DoubleLinkedList{
private Node head = new Node(0,"");
public Node getHead(){
return this.head;
}
// 遍历双向链表
public void list(){
if(head.next==null){
System.out.println("链表为空");
}
Node temp = head.next;
while(true){
if(temp==null){
break;
}
System.out.println(temp);
temp = temp.next;
}
}
// 添加(链表最后)
public void add(Node node){
Node temp = head;
while(true){
if(temp.next==null){
break;
}
temp = temp.next;
}
temp.next = node;
node.pre = temp;
}
// 添加(no顺序)
public void addOrder(Node noed){
Node temp = head;
boolean flag = false; //添加的编号是否已存在,默认false
while(true){
if(temp.next=null){ // 说明已经是链表的最后
break;
}
if(temp.next.no>node.no){ // 找到位置
break;
}else if(temp.next.no==node.no){// 编号已存在
flag = true;
break;
}
temp = temp.next;
}
// 如果flag=true
if(flag){
System.out.printf("改编号%d已存在\n",node.no);
}else{
node.next = temp.next;
temp.next = node;
node.pre = temp;
if(node.next!=null){
node.next.pre = node
}
}
}
// 修改
public void update(Node node){
// 判断是否为空
if(head.next == null){
System.out.println("链表为空");
return;
}
// 查询需要修改的节点
Node temp = head.next;
boolean flag = false;
while(true){
if(temp==null){
break;
}
if(temp.no == node.no){
flag = true;
break;
}
temp = temp.next;
}
// 根据flag判断是否找到修改的节点
if(flag){
temp.name = node.name;
}else{
// 没有找到
System.out.printf("没有找到编号%d节点\n",node.no);
}
}
// 删除节点
public void del(int no){
if(head.next==null){
// 空链表
System.out.println("链表为空");
}
Node temp = head.next;
boolean flag = false;
while(true){
if(temp == null){
break;
}
if(temp.no == no){
// 该节点
flag = true;
break;
}
temp = temp.next;
}
if(flag){
// 删除
temp.pre.next = temp.next;
if(temp.next!=null){
temp.next.pre = temp.pre;
}
}else{
System.out.printf("没有找到编号%d对应节点",no);
}
}
}
class Node{
public int no;
public String name;
public Node next;
public Node pre;
public Node(int no,String name){
this.no = no;
this.name = name;
}
public String toString(){
return "Node [no="+no+",name="+name+"]";
}
}
单向环形链表
- Josepfu问题
// 单向环形列表
public class CircleSingleLinkedList{
private Node first = null;
// 添加节点,构建环形链表
pulic void addNode(int nums){
if(nums<1){
System.out.println("nums不正确");
return;
}
Node cur = null;
for(int i=1;i<=nums;i++){
// 根据编号创建节点
Node n = new Node(i);
// 如果是第一个
if(i==1){
first = n;
first.next = first; // 构成环
cur = first;
}else{
cur.next = n;
n.next = first;
cur = n;
}
}
}
// 遍历当前链表
public void show(){
// 判断是否为空
if(first==null){
System.out.println("链表空");
return;
}
Node cur = first;
while(true){
System.ou.printf("当前编号%d",cur.no);
if(cur.next==first){
break;
}
cur = cur.next();
}
}
// Josepfu问题 取出的顺序
public void countNode(int startNo,int countNum,int nums){
// startNo 第几个节点开始
// countNum 间隔几个
// nums 最初有多少节点
if(first == null|| startNo<1 || startNo>nums){
System.out.println("输入参数有误");
return;
}
Node helper = first;
// 将helper指向最后一个节点
while(true){
if(helper.next==first){
break;
}
helper = helper.next;
}
//将first与helper移动到开始位置(startNo)
for(int j=0;j<startNo-1;j++){
first = first.next;
helper = helper.next;
}
while(true){
if(helper==first){
// 只有一个节点
break;
}
// 移动countNum - 1
for(int j=0;j<countNum-1;j++){
first = first.next;
helper = helper.next;
}
// 当前first出列
System.out.printf("编号%d出列",firsr.no);
first = first.next;
helper.next = first;
}
// 最后一个出列
System.out.printf("最后一个编号%d",firsr.no);
}
}
class Node{
public int no;
public Node next;
public Node(int no){
this.no = no;
}
}