目录
一、单链表的定义
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
实现自己的单链表MySingleList,能够对单链表进行简单的增删查改。
二、定义MySingleList的方法
用接口来定义MySingleList要实现的方法:
public interface IList {
//打印
void display();
//头插法
void addFist(int data);
//尾插法
void addLast(int data);
//在任意位置插入
void addIndex(int index,int data);
//查找关键字key是否在单链表中
boolean contains(int key);
//删除第一个关键字为key的节点
void remove(int key);
//删除所有为key的节点
void removeAllKey(int key);
//单链表长度
void size();
//清空单链表
void clear();
}
三、实现MySingleList的方法
实现接口定义的方法
1、定义节点
val |
next |
val 表示数据
next 表示指向下一个元素的地址
先创建一个节点内部类表示节点:
static class ListNode{ public int val; public ListNode next; public ListNode(int val) { this.val = val; } }
先放入几个默认数据:
public void createList(){ ListNode node1 = new ListNode(12); ListNode node2 = new ListNode(23); ListNode node3 = new ListNode(34); ListNode node4 = new ListNode(45); ListNode node5 = new ListNode(56); node1.next=node2; node2.next=node3; node3.next=node4; node4.next=node5; this.head=node1; }
public ListNode head;//定义head为第一个元素
2、遍历链表
public void display() {
while (head!=null){ //遍历整个链表
System.out.print(head.val+" ");
this.head=head.next;
}
System.out.println();
}
当遍历结束后,head会到达最后的位置,不能再表示头元素,所以创建一个新的对象来表示它,代替它完成遍历。
public void display() {
ListNode cur=this.head;
while (cur!=null){
System.out.print(cur.val+" ");
cur=cur.next;
}
System.out.println();
}
3、头插法
public void addFist(int data) {
ListNode node=new ListNode(data); //实例化要插入的节点
if (this.head==null){ //当链表为空时
this.head=node; //实例化的节点也就是首节点
}else {
node.next=this.head; //实例化的节点的next指向head
this.head=node; //首节点改为新实例化的节点
}
}
头插法为倒序排列
4、尾插法
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){ //遍历到链表最后一个节点的null
cur=cur.next;
}
cur.next=node; //让最后一个节点的next指向新实例化的节点,就可以尾插入
}
}
5、单链表长度
public int size() {
int count=0;
ListNode cur=this.head;
while (cur!=null){
count++;
cur=cur.next;
}
return count;
}
遍历链表,每经过一个节点count+1,最后返回count,就是单链表的长度。
6、判断单链表中包含的节点
对单链表中的节点进行遍历,判断是否找到目标节点。
public boolean contains(int key) {
ListNode cur=this.head;
while (cur!=null){
if (cur.val==key){
return true;
}
cur=cur.next;
}
return false;
}
7、指定位置插入
在指定位置插入数据,先判断插入位置的合法性,然后进行插入。记录插入位置的前一位置,将新插入节点的next指向前一位置的指向,让新插入的节点与后面的节点建立联系,然后前一位置指向新插入的节点。
@Override
public void addIndex(int index, int data) throws CheckIndex{
if (index<0 || index>size()){
throw new CheckIndex("插入位置错误");
}
if (index==0){
addFist(data);
return;
}
if (index==size()){
addLast(data);
return;
}
ListNode cur=searchPrev(index);
ListNode node=new ListNode(data);
node.next=cur.next;
cur.next=node;
}
private ListNode searchPrev(int index){ //找到前一位置
ListNode cur=this.head;
int count=0;
while (count!=index-1){ //一直走到要插入节点的前一位置
cur=cur.next;
count++;
}
return cur;
}
public class CheckIndex extends RuntimeException{
public CheckIndex(String msg){
super(msg);
}
}
8、删除节点
删除节点,将要删除节点的前一个节点的位置记录下来,然后将前一位置节点的next指向要删除节点后面的节点。
public void remove(int key) {
ListNode cur=findPrev(key);
if (cur==null){
System.out.println("没有找到你要删除的数字");
return;
}
ListNode del=cur.next; //del为要删除的节点
cur.next=del.next;
}
private ListNode findPrev(int key){
ListNode cur=this.head;
while (cur.next!=null){
if (cur.next.val==key){ //找到前一节点的位置
return cur;
}
cur=cur.next;
}
return null;
}
9、删除所有的相同节点
public void removeAllKey(int key) {
if (this.head==null){
return;
}
ListNode prev=head; //定义首节点
ListNode cur=head.next;
while (cur!=null){
if (cur.val==key){
prev.next=cur.next;//删除节点
cur=cur.next;
}else {
prev=cur;
cur=cur.next;
}
}
if (head.val==key){ //判断首节点
head=head.next;
}
}
10、清空单链表
清空单链表就是遍历单链表,然后将所有节点都置为空。
public void clear() {
ListNode cur=head;
while (cur!=null){
ListNode curNext=cur.next;
cur.next=null;
cur=curNext;
}
head=null;
}
四、使用MySingleList的方法
定义新的类,在main方法中可以对方法进行使用
public class Main {
public static void main(String[] args) {
MySingleList mySingleList=new MySingleList();
//mySingleList.createList();
//mySingleList.display();
mySingleList.addFist(1);
mySingleList.addFist(2);
mySingleList.addFist(2);
mySingleList.display();
mySingleList.addLast(6);
mySingleList.display();
mySingleList.addIndex(1,12);
mySingleList.display();
System.out.println(mySingleList.contains(2));
System.out.println(mySingleList.size());
mySingleList.remove(2);
mySingleList.display();
mySingleList.removeAllKey(2);
mySingleList.display();
mySingleList.clear();
}
}