链表是一种物理存储结构上非连续存储结构,数据元素的逻辑顺序是通过链表中的引用链接次序实现的 。
单链表无头非循环
// 1、无头单向非循环链表实现
public class SingleLinkedList {
//打印链表
public void display();
//头插法
public void addFirst(int data);
//尾插法
public void addLast(int data);
//任意位置插入,第一个数据节点为0号下标
public boolean addIndex(int index,int data);
//查找是否包含关键字key是否在单链表当中
public boolean contains(int key);
//删除第一次出现关键字为key的节点
public void remove(int key);
//删除所有值为key的节点
public void removeAllKey(int key);
//得到单链表的长度
public int size();
//清空链表
public void clear();
}
定义一个节点,一个放值,一个放他指向下一个节点的地址
大致就是这样子的一种链表,一个指一个
把第一个定义为头结点
注意,头不能移动,所以我们遍历要重新给头定义一个变量
class ListNode{ //定义一个节点
public int val; //
public ListNode next; //指向后一个节点
public ListNode(int val){ //构造方法
this.val = val;
}
}
public class MyLinkedList{
public ListNode head; //定义一个头结点
//打印链表
public void display(){
ListNode cur = this.head; //重新定义一个头结点,让源头节点不动
while(cur != null){ //遍历链表
System.out.print(cur.val+" "); //打印链表
cur = cur.next; //走向下一个节点
}
System.out.println(); // 换行
}
//获得链表长度
public int size(){
ListNode cur = this.head;
int count = 0; //定义一个计数量
while(cur != null){
count++; //遍历一个加一个
cur = cur.next;
}
return count; //返回遍历的长度
}
//判断链表中是否含有关键字key
public boolean contains(int key){
ListNode cur = this.head;
while(cur != null){
if(cur.val == key){ //如果等于要找的关键字
return true; //返回正确
}
cur = cur.next;
}
return false; //遍历完都没有找到,返回false
}
//头插法
public void addFirst(int data){
ListNode node = new ListNode(data); //定义要插的节点
node.next = this.head; //要插的节点的下一个节点地址先指向头
this.head = node; //要插节点变成新头
}
//尾插法
public void addLast(int data){
ListNode node = new ListNode(data);
if(this.head == null){ //头结点为空
this.head = node; //直接变成头插进去
}else{
ListNode cur = this.head;
while(cur.next != null){ //遍历到最后一个节点,因为最后一个节点的下一个指向是空
cur = cur.next;
}
cur.next = node; //最后节点下一个指向变成node,让node变成最后一个节点
}
}
/**
* 找到增加元素的前一个节点
* @param index
* @return
*/
public ListNode findIndex(int index){
ListNode cur = this.head;
while(index - 1 != 0){ //找到要增加位置前一个节点
cur = cur.next;
index--;
}
return cur; //返回找到的节点
}
//在任意位置增加元素,初始元素为0下标
public void addIndex(int index,int data){
if(index < 0 || index > size()){
System.out.println("index 位置不合法!");
return;
}
if(index == 0){ //头插法
addFirst(data);
return;
}
if(index == size()){ //尾插法
addLast(data);
return;
}
ListNode cur = findIndex(index); //找到的节点
ListNode node = new ListNode(data); //要插的节点
node.next = cur.next; //前一个节点下一个地址给现在插进去的节点的下一个地址
cur.next = node; //让前一个节点下一个地址变为现在插的节点地址
}
/**
* 找到要删除关键字的前驱
* @param key
* @return
*/
public ListNode search(int key){
ListNode cur = this.head;
while(cur.next != null){
if(cur.next.val == key){ //cur的下一个节点的值跟要删的一样
return cur; //返回cur
}
cur = cur.next;
}
return null; //没有要删的关键字
}
//删除第一次出现的关键字key
public void remove(int key){
if(this.head == null){
System.out.println("单链表为空,不能删除!");
return;
}
if(this.head.val == key){ //头结点是要删的
this.head = this.head.next; //头结点变为下一个
return;
}
ListNode cur = search(key);
if(cur == null){ //没找到
System.out.println("没有你要删的数!");
return;
}
ListNode del = cur.next; //要删的节点
cur.next = del.next; //让要删的前一个节点指向要删的后一个节点,这要要删的节点就没人引用,就删除了,被jvm回收
}
//删除所有关键字key
public ListNode removeAllKey(int key){
if(this.head == null){
return null;
}
ListNode prev = this.head; //定义头结点
ListNode cur = this.head.next; //定义头结点的下一个节点
while(cur != null){ //遍历
if(cur.val == key){ //找到要删的key
prev.next = cur.next; //直接让前一个节点指向后一个节点
cur = cur.next; //cur跳到后一个节点
}else{
prev = cur; //前一个不删,prev跳过去
cur = cur.next; //cur跟着跳
}
}
if(this.head.val == key){ //特殊情况,头结点是要删的,特殊处理
this.head = this.head.next;
}
return this.head;
}
//清空链表
public void clear(){
while(this.head != null){
ListNode curNext = this.head.next;
this.head.next = null;
this.head = curNext;
}
}
}
双链表无头循环
跟单链表差不多
// 2、无头双向链表实现
public class DoubleLinkedList {
//头插法
public void addFirst(int data);
//尾插法
public void addLast(int data);
//任意位置插入,第一个数据节点为0号下标
public boolean addIndex(int index,int data);
//查找是否包含关键字key是否在单链表当中
public boolean contains(int key);
//删除第一次出现关键字为key的节点
public void remove(int key);
//删除所有值为key的节点
public void removeAllKey(int key);
//得到单链表的长度
public int size();
public void display();
public void clear();
}
class ListNode{ //定义一个节点
public int val; //
public ListNode prev; //指向前一个节点
public ListNode next; //指向后一个节点
public ListNode(int val){ //构造方法
this.val = val;
}
}
public class MyDoubleLinkedList {
public ListNode head;
public ListNode last; //定义尾结点
//打印链表
public void display() {
ListNode cur = this.head;
while (cur != null) {
System.out.print(cur.val + " ");
cur = cur.next;
}
System.out.println();
}
//获得链表长度
public int size() {
ListNode cur = this.head;
int count = 0;
while (cur != null) {
count++;
cur = cur.next;
}
return count;
}
//判断链表中是否含有key
public boolean contains(int key) {
ListNode cur = this.head;
while (cur != null) {
if (cur.val == key) {
return true;
}
cur = cur.next;
}
return false;
}
//头插法
public void addFirst(int data) {
ListNode node = new ListNode(data);
if (this.head == null) { //防止prev为空,造成空指针异常
this.head = node;
this.last = node;
} else {
node.next = this.head;
this.head.prev = node;
this.head = node;
}
}
//尾插法
public void addLast(int data) {
ListNode node = new ListNode(data);
if (this.head == null) {
this.head = node;
this.last = node;
} else {
this.last.next = node;
node.prev = this.last;
this.last = node;
}
}
//找到要插的位置上的节点
public ListNode findIndex(int index) {
ListNode cur = this.head;
while (index != 0) {
cur = cur.next;
index--;
}
return cur;
}
//任意位置插入key,第一个数据节点为0下标
public void addIndex(int index, int data) {
if (index < 0 || index > size()) {
System.out.println("index 位置不合法!");
return;
}
if (index == 0) {
addFirst(data);
return;
}
if (index == size()) {
addLast(data);
return;
}
ListNode cur = findIndex(index);
ListNode node = new ListNode(data);
node.next = cur;
node.prev = cur.prev;
cur.prev.next = node;
cur.prev = node;
}
//删除第一次出现的key
public void remove(int key) {
ListNode cur = this.head;
while (cur != null) {
if (cur.val == key) {
if (cur == this.head) {
this.head = this.head.next;
}
if (this.head != null) {
this.head.prev = null;
} else {
this.last = null;
}
} else {
cur.prev.next = cur.next;
if (cur.next != null) {
cur.next.prev = cur.prev;
} else {
this.last = this.last.prev;
}
}
return;
}
cur = cur.next;
}
//删除所有出现的key
public void removeAllKey(int key) {
ListNode cur = this.head;
while (cur != null) {
if (cur.val == key) {
if (cur == head) {
head = head.next;
if (head != null) {
head.prev = null;
} else {
last = null;
}
} else {
cur.prev.next = cur.next;
if (cur.next != null) {
//中间位置
cur.next.prev = cur.prev;
} else {
last = last.prev;
}
}
}
cur = cur.next;
}
}
//清空链表
public void clear (){
while(this.head != null){
ListNode curNext = head.next;
head.next = null;
head.prev = null;
head = curNext;
}
last = null;
}
}
自用!!!