目录
3.1 addindex(int index,int data)方法的图形描述
1 单向带头循环单链表定义
单向带头循环单链表是指带有一个不存储数据的head结点,该结点指向下一个数据,且之后各个数据的指针单向的指向下一个结点,尾结点指向head的链表。以下通过图形来展示:
2 特点
- head中不存储数据,指针域指向下一个结点
- 尾结点的指针域存储head结点的指针
- 灵活、可进行存储空间的动态分配
- 插入、删除效率高
3 基本操作描述
3.1 addindex(int index,int data)方法的图形描述
首先判断index的合法性,若合法,调用函数找出index位置的前驱结点,将data插入即可。
3.2 remove(int key)方法的图形描述
3.3 ICLinked接口中的方法定义
public interface ICLinked {
//头插法
void addFirst(int data);
//尾插法
void addLast(int data);
//任意位置插入,第一个数据节点为0号下标
boolean addindex(int index,int data);
//查找是否包含关键字key是否在单链表当中
boolean contains(int key);
//删除第一次出现关键字为key的节点
int remove(int key);
//删除所有值为key的节点
void removeAllKey(int key);
//得到单链表的长度
int getLength();
void display();
void clear();
}
4 代码实现
public class MySingleImpl implements ICLinked{
class Node{
private int data;
private Node next;
public Node(int data) {
this.data = data;
this.next = null;
}
public Node() {
this.data = -1;
this.next = null;
}
}
private Node head;
public MySingleImpl() {
this.head = new Node();//无参构造创建一个循环的head结点
this.head.next = this.head;
}
@Override
public void addFirst(int data) {
Node node = new Node(data);
node.next = this.head.next;
this.head.next = node;
}
@Override
public void addLast(int data) {
Node node = new Node(data);
Node cur = this.head;
while (cur.next != this.head){
cur = cur.next;
}
node.next = this.head;
cur.next = node;
}
private void checkIndex(int index){
if(index < 0 || index > getLength()){
throw new UnsupportedOperationException("index位置不合法");
}
}
@Override
public boolean addindex(int index, int data) {
checkIndex(index);
Node cur = this.head;
for (int i = 0;i < index;i++){
cur = cur.next;
}//出了循环之后cur就是index位置的前驱
Node node = new Node(data);
node.next = cur.next;
cur.next = node;
return true;
}
@Override
public boolean contains(int key) {
Node cur = this.head.next;
while (cur != this.head){
if(cur.data == key){
return true;
}
cur = cur.next;
}
return false;
}
private Node searchPrev(int key){
Node cur = this.head;
while (cur.next != this.head){
if(cur.next.data == key){
return cur;
}
cur = cur.next;
}
return null;
}
//要删除一个包含key的节点,首先要找到这个节点的前驱节点
@Override
public int remove(int key) {
Node prev = searchPrev(key);
if(prev == null){
throw new UnsupportedOperationException("没有key");
}
Node cur = prev.next;
int oldnum = cur.data;
prev.next = cur.next;
return oldnum;
}
@Override
public void removeAllKey(int key) {
Node prev = searchPrev(key);
if (prev == null){
throw new UnsupportedOperationException("没有找到key");
}
Node cur = prev.next;
while (cur.next != this.head){
if(cur.data == key){
prev.next = cur.next;
cur = cur.next;
}else {
cur = cur.next;
prev = prev.next;
}
}
}
@Override
//取出数据节点的个数,头结点中没有存放数据!
public int getLength() {
int count = 0;
Node cur = this.head.next;
while (cur != this.head){
count++;
cur = cur.next;
}
return count;
}
@Override
public void display() {
Node cur = this.head.next;
while (cur != this.head){
System.out.print(cur.data+" ");
cur = cur.next;
}
System.out.println();
}
@Override
public void clear() {
//可以直接将head置为null,在此采取相对“温和”的操作
Node cur = this.head;
Node last = cur.next;
while (cur.next != this.head){
cur.next = last.next;
last = last.next;
}
this.head = null;
}
public static void main(String[] args) {
MySingleImpl mySingle = new MySingleImpl();
mySingle.addFirst(11);
mySingle.addFirst(22);
mySingle.addFirst(33);
mySingle.addFirst(44);
System.out.println("该单链表的长度为:"+mySingle.getLength());
mySingle.display();
mySingle.addLast(99);
mySingle.display();
System.out.println(mySingle.contains(93));
mySingle.addindex(0,10);
System.out.println(mySingle.getLength());
mySingle.addindex(6,88);
mySingle.display();
System.out.println("删除的值为:"+mySingle.remove(33));
mySingle.display();
mySingle.addindex(4,44);
mySingle.addindex(5,44);
mySingle.display();
mySingle.removeAllKey(44);
mySingle.display();
mySingle.clear();//清空单链表防止内存泄露
}
}
5 运行结果