数据结构与算法之单向链表
基本介绍
- 链表是以结点的方式来存储的
- 每个结点包含data域和next域
- 每个结点不一定连续
- 带有头结点或不带有头结点
特点:非连续的存储结构,每个结点都有下一个结点的内存地址,缺点是查找时要从第一个开始逐个查找
代码示例
class SingleLinkedList{
private Node head = new Node(0,"");
public void add(Node n){
Node temp = head;
while(temp.getNext() != null){
temp = temp.getNext();
}
temp.setNext(n);
}
public void addById(Node n){
Node temp = head;
while(temp.getNext() != null){
if(temp.getNext().getId() > n.getId()){
break;
}else if(temp.getNext().getId() == n.getId()){
System.out.println(n.getId()+"已存在,无法添加");
return;
}
temp = temp.getNext();
}
n.setNext(temp.getNext());
temp.setNext(n);
}
public void updateById(Node n){
Node temp = head;
boolean flag = false;
while(temp.getNext() != null){
if(temp.getNext().getId() == n.getId()){
flag = true;
break;
}
temp = temp.getNext();
}
if(!flag){
System.out.println("没有该ID存在");
return ;
}
Node last = temp.getNext().getNext();
temp.setNext(n);
n.setNext(last);
}
public void delById(int id){
Node temp = head;
boolean flag = false;
while(temp.getNext() != null){
if(temp.getNext().getId() == id){
flag = true;
break;
}
temp = temp.getNext();
}
if(!flag){
System.out.println("没有该ID存在");
return ;
}
temp.setNext(temp.getNext().getNext());
}
public void list(){
if(head.getNext() == null){
System.out.println("链表为空");
return;
}
Node temp = head;
while (temp.getNext() != null){
System.out.println(temp = temp.getNext());
}
}
}
class Node{
private String name;
private Node next;
private int id;
public Node(int id,String name) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "Node{" +
"name='" + name + '\'' +
", id=" + id +
'}';
}
}
常见问题
- 求单链表的有效节点个数
public int size(){
int size = 0;
Node temp = head;
while (temp.getNext() != null){
temp = temp.getNext();
size++;
}
return size;
}
- 查找单链表的倒数第K个结点
public Node getByLastIndex(int i){
int index = size() - i + 1;
if(index <= 0 || index > size()){
throw new RuntimeException("没有该位置");
}
Node temp = head;
int count = 0;
while (count ++ != index){
temp = temp.getNext();
}
return temp;
}
- 反转
public void reverse(){
if(head.getNext() == null || head.getNext().getNext() == null){
return;
}
Node reverseHead = new Node(0,"");
Node cur = head.getNext();
while (cur != null){
Node next = cur.getNext();
cur.setNext(reverseHead.getNext());
reverseHead.setNext(cur);
cur = next;
}
head.setNext(reverseHead.getNext());
}
- 从尾到头打印单链表
public void listReverse(){
print(head);
}
private void print(Node node){
if(node.getNext() != null){
print(node.getNext());
}
if(node != head){
System.out.println(node);
}
}
- 合并两个有序的单链表,合并后依然有序
public void merge(SingleLinkedList list){
if(list == null){
throw new RuntimeException("不能为null");
}
if(list.head.getNext() == null){
return;
}
Node next = list.head.getNext();
Node[] nodes = new Node[list.size()];
for(int i = 0; i < list.size() ; i++){
nodes[i] = next;
next = next.getNext();
}
for (Node node : nodes) {
addById(node);
}
}