大话数据结构四:线性表的链式存储结构(单向循环链表)

1. 单向循环链表:将单链表尾结点的指针端由空指针改为指向头结点,使整个单链表形成一个环,这种头尾相接的单链表称为单向循环链表。
 

2. 单向循环链表和单链表实现的区别:

1.)添加一个结点到单向循环链表末尾时,必须使其最后一个结点的指针指向表头结点,而不是象单链表那样置为null。

2.)判断是否到达表尾时,单向循环链表可以判断该结点是否指向头结点,单链表只需要知道是否为null。
 

3.Java实现单向循环链表:

// 单向循环链表
public class CircularLinkedList<E> {
    private Node<E> tail; // 尾结点
    private int size; // 链表长度  

    public CircularLinkedList() {
        tail = null;
        size = 0;
    }  

    // 在头结点前插入
    public boolean addBeforeHead(E data){
        Node<E> newNode = new Node<E>(data);
        if(isEmpty()){
            tail = newNode;
            tail.setNext(newNode); // 尾结点指向头结点
            newNode.setNext(tail); // 头结点指向尾结点
        }else{
            Node<E> head = tail.getNext();
            tail.setNext(newNode);
            newNode.setNext(head);
        }
        size++;
        return true;
    }  

    // 在尾结点后插入
    public boolean addAfterTail(E data){
        Node<E> newNode = new Node<E>(data);
        if(isEmpty()){
            tail = newNode;
            tail.setNext(newNode);
            newNode.setNext(tail);
        }else{
            Node<E> head = tail.getNext(); // 获取头结点
            tail.setNext(newNode); // 将原尾结点指向新结点
            tail = newNode; // 将新节点设置为尾结点
            newNode.setNext(head); // 将新尾结点指向头结点
        }
        size++;
        return true;
    }  

    // 在某位置上插入(position为结点位置,不是角标)
    public boolean insert(int position,E data){
        if(position >= 1 && (position <= size + 1)){
            if(isEmpty() || position == 1){ // 在头结点前插入
                addBeforeHead(data);
            }else if(position == size + 1){ // 在尾结点后插入
                addAfterTail(data);
            }else{ // 在中间位置插入
                Node<E> preNode = get(position - 1); // 获取position的前一结点
                Node<E> originalNode = preNode.getNext(); // 获取未插入结点时position位置对应结点
                Node<E> newNode = new Node<E>(data);
                preNode.setNext(newNode);
                newNode.setNext(originalNode);
                size++;
                return true;
            }
        }
        return false;
    }  

    // 删除对应位置的结点
    public E delete(int position){
        E result = null;
        if(position >= 1 && position <= size){
            if(position == 1){ // 删除头结点
                result = tail.getNext().getData();
                Node<E> afterHead = tail.getNext().getNext();
                tail.setNext(afterHead);
            }else if(position == size){ // 删除尾结点
                result = tail.getData();
                Node<E> preTail = get(position - 1);
                preTail.setNext(tail.getNext());
                tail = preTail;
                size--;
            }else{ // 删除其他结点
                Node<E> preNode = get(position - 1);
                Node<E> curNode = preNode.getNext();
                result = curNode.getData();
                preNode.setNext(curNode.getNext());
                size--;
            }
        }
        return result;
    }  

    // 获取某个位置的结点
    public Node<E> get(int position){
        Node<E> targetNode = null;
        if(!isEmpty() && position >= 1 && position <= size){
            targetNode = tail.getNext(); // 获取头结点
            for(int i = 1; i < position ; i++){
                targetNode = targetNode.getNext(); // 循环获取对应位置的结点
            }
        }
        return targetNode;
    }  

    // 获取链表的长度
    public int getSize(){
        return size;
    }  

    // 判断链表是否为空
    public boolean isEmpty(){
        return size == 0;
    }  

    // 打印链表中的数据
    public void display(){
        Node<E> node = tail.getNext();  // 获取头结点
        System.out.print("单向循环链表: ");
        for(int i = 0; i < size; i++){
            System.out.print(" " + node.getData());
            node = node.getNext();
        }
        System.out.println("");
    }
}
// 结点类,包含结点的数据和指向下一个节点的引用
public class Node<E> {
    private E data; // 数据域
    private Node<E> next; // 指针域保存着下一节点的引用  

    public Node() {
    }  

    public Node(E data) {
        this.data = data;
    }  

    public Node(E data, Node<E> next) {
        this.data = data;
        this.next = next;
    }  

    public E getData() {
        return data;
    }  

    public void setData(E data) {
        this.data = data;
    }  

    public Node<E> getNext() {
        return next;
    }  

    public void setNext(Node<E> next) {
        this.next = next;
    }
}

更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/sjjg/

// 测试类
public class Main {
    public static void main(String[] args) {
        CircularLinkedList<Integer> circular = new CircularLinkedList<Integer>();
        circular.addBeforeHead(3);
        circular.addBeforeHead(2);
        circular.addBeforeHead(1);
        circular.addAfterTail(4);
        circular.addAfterTail(5);
        circular.addAfterTail(6);
        circular.insert(1,0);
        circular.insert(8,7);
        circular.insert(5,8);
        circular.delete(5);
        circular.display();
        System.out.println("链表的长度为: " + circular.getSize());
    }
}

作者:csdn博客 zdp072

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索单链表
, 线性表
, 数据结构 单链表
, 单链表的顺序
, node
, 单链表 数据结构 c++
, 结点
, position
, 循环链表
, mode getnext
, tail
, 单向循环链表
, java单链表
单链
,以便于您获取更多的相关知识。

时间: 2024-10-12 07:01:30

大话数据结构四:线性表的链式存储结构(单向循环链表)的相关文章

大话数据结构二:线性表的链式存储结构(单链表)

1. 线性表的链式存储结构:指的是用一组任意的存储单元存储线性表的数据元素,这组存储单元可以是连续的,也可以是不连续的,这就意味着这些数据元素可以存在内存未被占用的任意位置. 2. 结点:结点由存放数据元素的数据域和存放后继结点地址的指针域组成. 1.)顺序存储结构中,每个数据元素只需要存数据元素的信息就可以了. 2.)链式存储结构中,除了要存储数据元素信息外,还要存储它的后继元素的存储地址. 3.)链表中第一个结点叫头结点,它的存储位置叫做头指针,它的数据域可以不存储任何信息,链表的最后一个结

大话数据结构五:线性表的链式存储结构(双向链表)

1. 双向链表:在单链表的每个结点中,再设置一个指向其前驱结点的指针域,那么在双向链表中的结点都有两个指针域,一个指向直接后继,另一个指向直接前驱. 2. 单链表和双向链表比较: 单链表:总是要从头到尾找结点,只能正遍历,不能反遍历. 双向链表: 可以从头找到尾,也可以从尾找到头,即正反遍历都可以,可以有效提高算法的时间性能,但由于每个结点需要记录两份指针,所以在空间占用上略多一点,这就是通过空间来换时间. 3. Java实现双向链表: // 双向链表 public class DoubleLi

大话数据结构三:线性表的链式存储结构(静态链表)

1. 静态链表:用数组描述的链表叫静态链表,通常为方便数据插入,我们会把数组建的大一些. 2. 数组元素(node):由两个数据域组成(data,cursor).数据域data用来存放数据元素,也就是通常我们要处理的数据:而cursor相当于单链表中的指针,存放该元素的后继在数组中的下标. 3. Java实现静态链表: // 静态链表 class StaticLinkedList { private int size; private Node[] node = new Node[100]; /

艾伟_转载:C#版数据结构之--线性表的链式存储(单链表)

1.单链表的定义和由来: 链表是用一组地址可能连续也可能不连续的存储单元来存储线性表中的数据元素,在存储数据元素时,除了要存储数据元素本身之外,还要存储与它相邻的数据元素的地址信息,这两部分组成了线性表中一个数据元素的映像,称之为"结点",存储数据元素本身的部分称之为:数据域,存储相邻数据元素地址的部分称之为:地址域,所有节点通过地址域链接起来,像一个链条,故用此种方式存储的线性表称之为:链表.如果节点的地址域只存储了数据元素的直接后继的存储地址,则称这种链表为:单链表. 与数序表相比

C#版数据结构之--线性表的链式存储(单链表)

1.单链表的定义和由来: 链表是用一组地址可能连续也可能不连续的存储单元来存储线性表中的数据元素,在存储数据元素时,除了要存储数据元素本身之外,还要存储与它相邻的数据元素的地址信息,这两部分组成了线性表中一个数据元素的映像,称之为"结点",存储数据元素本身的部分称之为:数据域,存储相邻数据元素地址的部分称之为:地址域,所有节点通过地址域链接起来,像一个链条,故用此种方式存储的线性表称之为:链表.如果节点的地址域只存储了数据元素的直接后继的存储地址,则称这种链表为:单链表. 与数序表相比

大话数据结构九:队列的链式存储结构(链队列)

1. 链队列的特点: 链队列其实就是单链表,只不过它是先进先出的单链表,为了实现方便,程序中设置了队头(front),队尾(rear)两个指针. 2. Java使用链表实现队列: //结点类,包含结点的数据和指向下一个节点的引用 public class Node<E> { private E data; // 数据域 private Node<E> next; // 指针域保存着下一节点的引用 public Node() { } public Node(E data) { thi

大话数据结构十三:二叉树的链式存储结构(二叉链表)

1. 关于树 ① 树的度 - 也即是宽度,简单地说,就是结点的分支数. ② 树的深度 - 组成该树各结点的最大层次. ③ 森林 - 指若干棵互不相交的树的集合. ④ 有序树 - 指树中同层结点从左到右有次序排列,它们之间的次序不能互换,这样的树称为有序树,否则称为无序树. 2. 二叉树的特点 i.每个结点最多有两颗子树 ii.左子树和右子树是有顺序的,次序不能任意颠倒 iii.即使树中某结点只有一颗子树,也要区分它是左子树还是右子树 3. 二叉树五种形态 ① 空二叉树 ② 只有一个根结点 ③ 根

线性表的链式表示

以下为操作链表的算法,该链表为动态单链表. 链表以头指针为索引,头指针指向头节点,头节点指向首节点,以此类推,直到尾节点. 头节点中不存放数据,只存放指向首节点的指针, 设置头节点的目的是为了方便对链表的操作,如果不设置头节点,而是直接由头指针指向首节点, 这样在对头指针后的节点进行插入删除操作时就会与其他节点进行该操作时有所不同,便要作为一种特殊情况来分析 操作系统:ubuntu 编译软件:gcc 结果截图: 源代码: #include<stdio.h> #include<stdlib

数据结构教程 第八课 线性表的链式表示与实现

本课主题: 线性表的链式表示与实现 教学目的: 掌握线性链表.单链表.静态链表的概念.表示及实现方法 教学重点: 线性链表之单链表的表示及实现方法. 教学难点: 线性链表的概念. 授课内容: 一.复习顺序表的定义. 二.线性链表的概念: 以链式结构存储的线性表称之为线性链表. 特点是该线性表中的数据元素可以用任意的存储单元来存储.线性表中逻辑相邻的两元素的存储空间可以是不连续的.为表示逻辑上的顺序关系,对表的每个数据元素除存储本身的信息之外,还需存储一个指示其直接衙继的信息.这两部分信息组成数据