队列练习之Example002-用带头结点的循环链表表示队列,并且只设一个指针指向队尾结点,实现对应的入队列和出队列的算法

这篇具有很好参考价值的文章主要介绍了队列练习之Example002-用带头结点的循环链表表示队列,并且只设一个指针指向队尾结点,实现对应的入队列和出队列的算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Example002

题目

假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾结点,但不设头指针,请写出相应的入队列和出队列的算法。

分析

注意,这里的不设头指针的意思是不设定队头指针。

我们设 rear 为带头结点的循环链队的尾指针,但 rear 却不是指向循环链队的头结点,而是指向循环链队的队尾结点。

本题是链队基本操作的扩展,知道尾指针后,要实现元素入队,则直接用链表的插入操作即可。要实现出队操作,则需要根据尾指针找出头结点和开始结点,然后进行删除。要注意的是,尾指针应始终指向终端结点,并且当删除结点后队列为空时,必须特殊处理

注意:在解题时不必考虑结点的结构体,其实这里只需要用到单链表结点 LNode 就可以了,即只需要一个 next 指针就可以了,下面之所以使用 CLNode 结点并添加一个 rear 指针,是为了便于测试方法而写出来的。实际解题只需要在参数列表中传入队尾指针 rear 即可,不需要去考虑如何它是如何来的。如果下面的测试代码用的是单链表结点 LNode`,那么如果想要传入队尾指针作为参数,那么需要遍历单链表找到队尾结点,然后作为参数传入,当然这些都不在解题的考虑范围内。之所以解释这一段,也是因为我们不能只写具体算法,还要写能够测试写出来算法是否有效的其他代码。

图解

有点不太好理解,其实画个图就很容易看明白了,就是链表的插入和删除操作而已。

  • 循环链队如图

假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾结点,但不设头指针,,数据结构,数据结构,链队,队列,链表

  • 循环链队元素入队如图

假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾结点,但不设头指针,,数据结构,数据结构,链队,队列,链表

  • 循环链队元素出队如图

假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾结点,但不设头指针,,数据结构,数据结构,链队,队列,链表

C实现

核心代码:

/**
 * 将元素入队
 * @param rear 循环链式队列的尾指针,指向链式队列的尾结点
 * @param ele 待入队的元素
 */
void enQueue(CLNode **rear, int ele) {
    // 1.创建新结点
    // 1.1 为新结点分配存储空间
    CLNode *newNode = (CLNode *) malloc(sizeof(CLNode));
    // 1.2 为新结点指定数据域
    newNode->data = ele;
    // 1.2 为新结点指定指针域,新结点的指针域初始都指向 null
    newNode->next = NULL;

    // 2.将新结点入队
    // 2.1 将新结点的 next 指针指向原队尾结点的后继结点。即将新结点与原队列头结点连接起来
    // 实际上 rear 指向队尾结点;rear->next 由于是循环链式队列,所以指向的是头结点
    newNode->next = (*rear)->next;
    // 2.2 将原队尾结点的 next 指针指向新结点。即将原队列尾与新结点连接起来,才构成一个循环链
    (*rear)->next = newNode;
    // 2.3 将队尾指针指向新结点,即此时新结点成为了队列的队尾结点
    (*rear) = newNode;
}

/**
 * 将元素出队
 * @param rear 循环链式队列的尾指针,指向链式队列的尾结点
 * @param ele 保存出队的元素
 * @return 如果出队成功则返回 1,否则返回 0 表示出队失败
 */
int deQueue(CLNode **rear, int *ele) {
    // 0.参数校验,如果是空队列,则返回 0 表示不能出队。注意循环链表的判空条件
    if ((*rear)->next == *rear) {
        return 0;
    }

    // 其中 rear 指向队尾结点;rear->next 由于是循环链式队列,所以指向的是头结点
    // 局部变量,头结点
    CLNode *headNode = (*rear)->next;
    // 局部变量,开始结点。而头结点的后继结点就是开始结点
    CLNode *startNode = headNode->next;

    // 1.用 ele 保存开始结点的数据域,因为队列是从队头出队,所以就是出队开始结点
    *ele = startNode->data;
    // 2.删除队头结点。即将队头结点的 next 指针指向原开始结点的后继结点
    headNode->next = startNode->next;
    // 如果元素出队后队列为空,则需要特殊处理
    if (startNode==*rear){
        *rear=(*rear)->next;
    }
    // 3.释放被删结点的空间
    free(startNode);
    // 4.返回 1 表示出队成功
    return 1;
}

完整代码:

#include<stdio.h>
#include<stdlib.h>

/**
 * 链式循环队列结点结构体定义
 */
typedef struct CLNode {
    /**
     * 结点数据域,存储结点的数据值
     */
    int data;
    /**
     * 结点指针域,存储当前结点的后继结点的地址
     */
    struct CLNode *next;
    /**
     * 结点指针域,即队尾指针,指向队尾结点,存储队列尾结点的地址
     */
    struct CLNode *rear;
} CLNode;

/**
 * 初始化队列
 * @param queue 未初始化的队列
 */
void init(CLNode **queue) {
    // 创建头结点,queue 即为链式队列的头结点,为头结点分配空间
    *queue = (CLNode *) malloc(sizeof(CLNode));
    // 将链式队列头结点的 next 和 rear 指针都指向自身,因为是循环的,并且是空队列
    (*queue)->next = *queue;
    (*queue)->rear = *queue;
}

/**
 * 将元素入队
 * @param rear 循环链式队列的尾指针,指向链式队列的尾结点
 * @param ele 待入队的元素
 */
void enQueue(CLNode **rear, int ele) {
    // 1.创建新结点
    // 1.1 为新结点分配存储空间
    CLNode *newNode = (CLNode *) malloc(sizeof(CLNode));
    // 1.2 为新结点指定数据域
    newNode->data = ele;
    // 1.2 为新结点指定指针域,新结点的指针域初始都指向 null
    newNode->next = NULL;

    // 2.将新结点入队
    // 2.1 将新结点的 next 指针指向原队尾结点的后继结点。即将新结点与原队列头结点连接起来
    // 实际上 rear 指向队尾结点;rear->next 由于是循环链式队列,所以指向的是头结点
    newNode->next = (*rear)->next;
    // 2.2 将原队尾结点的 next 指针指向新结点。即将原队列尾与新结点连接起来,才构成一个循环链
    (*rear)->next = newNode;
    // 2.3 将队尾指针指向新结点,即此时新结点成为了队列的队尾结点
    (*rear) = newNode;
}

/**
 * 将元素出队
 * @param rear 循环链式队列的尾指针,指向链式队列的尾结点
 * @param ele 保存出队的元素
 * @return 如果出队成功则返回 1,否则返回 0 表示出队失败
 */
int deQueue(CLNode **rear, int *ele) {
    // 0.参数校验,如果是空队列,则返回 0 表示不能出队。注意循环链表的判空条件
    if ((*rear)->next == *rear) {
        return 0;
    }

    // 其中 rear 指向队尾结点;rear->next 由于是循环链式队列,所以指向的是头结点
    // 局部变量,头结点
    CLNode *headNode = (*rear)->next;
    // 局部变量,开始结点。而头结点的后继结点就是开始结点
    CLNode *startNode = headNode->next;

    // 1.用 ele 保存开始结点的数据域,因为队列是从队头出队,所以就是出队开始结点
    *ele = startNode->data;
    // 2.删除队头结点。即将队头结点的 next 指针指向原开始结点的后继结点
    headNode->next = startNode->next;
    // 如果元素出队后队列为空,则需要特殊处理
    if (startNode==*rear){
        *rear=(*rear)->next;
    }
    // 3.释放被删结点的空间
    free(startNode);
    // 4.返回 1 表示出队成功
    return 1;
}

/**
 * 打印循环链式队列
 * @param queue 队列
 */
void print(CLNode *queue) {
    printf("[");
    CLNode *node = queue->next;
    while (node != queue) {
        printf("%d", node->data);
        if (node->next != queue) {
            printf(", ");
        }
        node = node->next;
    }
    printf("]\n");
}

int main() {
    // 声明队列
    CLNode *queue;

    // 初始化队列
    printf("\n初始化队列:\n");
    init(&queue);
    print(queue);

    // 将元素入队
    printf("\n将元素入队:\n");
    // 这里传入的参数可能有点难以理解,因为 enQueue 方法的第一个参数是双指针,所以传入的是指针变量的地址
    // queue是一个指针变量;&queue就是指针变量的地址,而queue->rear是为了获取队列的队尾指针,将队尾指针作为参数传入而非在函数内获取,是为了更直观了解函数的功能
    enQueue(&(queue->rear), 11);
    print(queue);
    enQueue(&(queue->rear), 22);
    print(queue);
    enQueue(&(queue->rear), 33);
    print(queue);
    enQueue(&(queue->rear), 44);
    print(queue);
    enQueue(&(queue->rear), 55);
    print(queue);
    enQueue(&(queue->rear), 66);
    print(queue);

    // 将元素出队
    printf("\n将元素出队:\n");
    int ele;
    deQueue(&(queue->rear), &ele);
    printf("出队元素:%d\n", ele);
    print(queue);
    deQueue(&(queue->rear), &ele);
    printf("出队元素:%d\n", ele);
    print(queue);
    deQueue(&(queue->rear), &ele);
    printf("出队元素:%d\n", ele);
    print(queue);
}

执行结果:

初始化队列:
[]

将元素入队:
[11]
[11, 22]
[11, 22, 33]
[11, 22, 33, 44]
[11, 22, 33, 44, 55]
[11, 22, 33, 44, 55, 66]

将元素出队:
出队元素:11
[22, 33, 44, 55, 66]
出队元素:22
[33, 44, 55, 66]
出队元素:33
[44, 55, 66]

上面是纯 C 语言实现,而通常数据结构题目中会使用 & 来引用,而这属于 C++ 语言范畴,但这样更便于理解函数的功能,而非陷入 C 语言语法中忽略了算法的本质。但使用了 & 语法的代码在纯 C 语言编译器是无法通过编译的,可以使用 Dev-C++ 来执行代码。所以代码如下:

#include<stdio.h>
#include<stdlib.h>

/**
 * 链式循环队列结点结构体定义
 */
typedef struct CLNode {
    /**
     * 结点数据域,存储结点的数据值
     */
    int data;
    /**
     * 结点指针域,存储当前结点的后继结点的地址
     */
    struct CLNode *next;
    /**
     * 结点指针域,即队尾指针,指向队尾结点,存储队列尾结点的地址
     */
    struct CLNode *rear;
} CLNode;

/**
 * 初始化队列
 * @param queue 未初始化的队列
 */
void init(CLNode *&queue) {
    // 创建头结点,queue 即为链式队列的头结点,为头结点分配空间
    queue = (CLNode *) malloc(sizeof(CLNode));
    // 将链式队列头结点的 next 和 rear 指针都指向自身,因为是循环的,并且是空队列
    queue->next = queue;
    queue->rear = queue;
}

/**
 * 将元素入队
 * @param rear 循环链式队列的尾指针,指向链式队列的尾结点
 * @param ele 待入队的元素
 */
void enQueue(CLNode *&rear, int ele) {
    // 1.创建新结点
    // 1.1 为新结点分配存储空间
    CLNode *newNode = (CLNode *) malloc(sizeof(CLNode));
    // 1.2 为新结点指定数据域
    newNode->data = ele;
    // 1.2 为新结点指定指针域,新结点的指针域初始都指向 null
    newNode->next = NULL;

    // 2.将新结点入队
    // 2.1 将新结点的 next 指针指向原队尾结点的后继结点。即将新结点与原队列头结点连接起来
    // 实际上 rear 指向队尾结点;rear->next 由于是循环链式队列,所以指向的是头结点
    newNode->next = rear->next;
    // 2.2 将原队尾结点的 next 指针指向新结点。即将原队列尾与新结点连接起来,才构成一个循环链
    rear->next = newNode;
    // 2.3 将队尾指针指向新结点,即此时新结点成为了队列的队尾结点
    rear = newNode;
}

/**
 * 将元素出队
 * @param rear 循环链式队列的尾指针,指向链式队列的尾结点
 * @param ele 保存出队的元素
 * @return 如果出队成功则返回 1,否则返回 0 表示出队失败
 */
int deQueue(CLNode *&rear, int *ele) {
    // 0.参数校验,如果是空队列,则返回 0 表示不能出队。注意循环链表的判空条件
    if (rear->next == rear) {
        return 0;
    }

    // 其中 rear 指向队尾结点;rear->next 由于是循环链式队列,所以指向的是头结点
    // 局部变量,头结点
    CLNode *headNode = rear->next;
    // 局部变量,开始结点。而头结点的后继结点就是开始结点
    CLNode *startNode = headNode->next;

    // 1.用 ele 保存开始结点的数据域,因为队列是从队头出队,所以就是出队开始结点
    *ele = startNode->data;
    // 2.删除队头结点。即将队头结点的 next 指针指向原开始结点的后继结点
    headNode->next = startNode->next;
    // 如果元素出队后队列为空,则需要特殊处理
    if (startNode==*rear){
        *rear=(*rear)->next;
    }
    // 3.释放被删结点的空间
    free(startNode);
    // 4.返回 1 表示出队成功
    return 1;
}

/**
 * 打印循环链式队列
 * @param queue 队列
 */
void print(CLNode *queue) {
    printf("[");
    CLNode *node = queue->next;
    while (node != queue) {
        printf("%d", node->data);
        if (node->next != queue) {
            printf(", ");
        }
        node = node->next;
    }
    printf("]\n");
}

int main() {
    // 声明队列
    CLNode *queue;

    // 初始化队列
    printf("\n初始化队列:\n");
    init(queue);
    print(queue);

    // 将元素入队
    printf("\n将元素入队:\n");
    // 这里传入的参数可能有点难以理解,因为 enQueue 方法的第一个参数是双指针,所以传入的是指针变量的地址
    // queue是一个指针变量;&queue就是指针变量的地址,而queue->rear是为了获取队列的队尾指针,将队尾指针作为参数传入而非在函数内获取,是为了更直观了解函数的功能
    enQueue(queue->rear, 11);
    print(queue);
    enQueue(queue->rear, 22);
    print(queue);
    enQueue(queue->rear, 33);
    print(queue);
    enQueue(queue->rear, 44);
    print(queue);
    enQueue(queue->rear, 55);
    print(queue);
    enQueue(queue->rear, 66);
    print(queue);

    // 将元素出队
    printf("\n将元素出队:\n");
    int ele;
    deQueue(queue->rear, &ele);
    printf("出队元素:%d\n", ele);
    print(queue);
    deQueue(queue->rear, &ele);
    printf("出队元素:%d\n", ele);
    print(queue);
    deQueue(queue->rear, &ele);
    printf("出队元素:%d\n", ele);
    print(queue);
}

Java实现

核心代码:

    /**
     * 将元素入队
     *
     * @param ele 待入队的元素
     */
    public void enQueue(int ele) {
        // 1.创建新结点
        // 1.1 为新结点分配存储空间
        CLNode newNode = new CLNode();
        // 1.2 为新结点指定数据域
        newNode.data = ele;
        // 1.2 为新结点指定指针域,新结点的指针域初始都指向 null
        newNode.next = null;

        // 2.将新结点入队
        // 2.1 将新结点的 next 指针指向原队尾结点的后继结点。即将新结点与原队列头结点连接起来
        // 实际上 queue.rear 指向队尾结点;queue.rear.next 由于是循环链式队列,所以指向的是头结点
        newNode.next = queue.rear.next;
        // 2.2 将原队尾结点的 next 指针指向新结点。即将原队列尾与新结点连接起来,才构成一个循环链
        queue.rear.next = newNode;
        // 2.3 将队尾指针指向新结点,即此时新结点成为了队列的队尾结点
        queue.rear = newNode;
    }

    /**
     * 将元素出队
     *
     * @return 出队的元素
     * @throws Exception 如果队列为空则抛出该异常
     */
    public int deQueue() throws Exception {
        // 0.参数校验,如果是空队列,则抛出异常表示不能出队。注意循环链表的判空条件
        if (queue.rear == queue) {
            throw new Exception("空队列无法出队!");
        }

        // 其中 queue 表示头指针,指向队列的头结点,queue.rear 表示队尾指针,指向队尾结点;queue.rear.next 由于是循环链式队列,所以指向的是头结点
        // 局部变量,头结点
        CLNode headNode = queue.rear.next;
        // 局部变量,开始结点。而头结点的后继结点就是开始结点
        CLNode startNode = headNode.next;

        // 1.保存开始结点的数据域,因为队列是从队头出队,所以就是出队开始结点
        int data = startNode.data;
        // 2.删除队头结点。即将队头结点的 next 指针指向原开始结点的后继结点
        headNode.next = startNode.next;
        // 如果元素出队后队列为空,则需要特殊处理
        if (startNode == queue.rear) {
            queue.rear = queue.rear.next;
        }
        // 3.释放被删结点的空间
        startNode.next = null;
        startNode = null;
        // 4.返回出队元素
        return data;
    }

完整代码:

public class Queue {
    /**
     * 声明链式循环队列,queue 即链式循环队列的头结点
     */
    private CLNode queue;

    /**
     * 初始化队列
     */
    public void init() {
        // 初始化链式队列
        queue = new CLNode();
        // 将链式队列头结点的 next 和 rear 指针都指向自身,因为是循环的,并且是空队列
        queue.next = queue;
        queue.rear = queue;
    }

    /**
     * 将元素入队
     *
     * @param ele 待入队的元素
     */
    public void enQueue(int ele) {
        // 1.创建新结点
        // 1.1 为新结点分配存储空间
        CLNode newNode = new CLNode();
        // 1.2 为新结点指定数据域
        newNode.data = ele;
        // 1.2 为新结点指定指针域,新结点的指针域初始都指向 null
        newNode.next = null;

        // 2.将新结点入队
        // 2.1 将新结点的 next 指针指向原队尾结点的后继结点。即将新结点与原队列头结点连接起来
        // 实际上 queue.rear 指向队尾结点;queue.rear.next 由于是循环链式队列,所以指向的是头结点
        newNode.next = queue.rear.next;
        // 2.2 将原队尾结点的 next 指针指向新结点。即将原队列尾与新结点连接起来,才构成一个循环链
        queue.rear.next = newNode;
        // 2.3 将队尾指针指向新结点,即此时新结点成为了队列的队尾结点
        queue.rear = newNode;
    }

    /**
     * 将元素出队
     *
     * @return 出队的元素
     * @throws Exception 如果队列为空则抛出该异常
     */
    public int deQueue() throws Exception {
        // 0.参数校验,如果是空队列,则抛出异常表示不能出队。注意循环链表的判空条件
        if (queue.rear == queue) {
            throw new Exception("空队列无法出队!");
        }

        // 其中 queue 表示头指针,指向队列的头结点,queue.rear 表示队尾指针,指向队尾结点;queue.rear.next 由于是循环链式队列,所以指向的是头结点
        // 局部变量,头结点
        CLNode headNode = queue.rear.next;
        // 局部变量,开始结点。而头结点的后继结点就是开始结点
        CLNode startNode = headNode.next;

        // 1.保存开始结点的数据域,因为队列是从队头出队,所以就是出队开始结点
        int data = startNode.data;
        // 2.删除队头结点。即将队头结点的 next 指针指向原开始结点的后继结点
        headNode.next = startNode.next;
       	// 如果元素出队后队列为空,则需要特殊处理
        if (startNode == queue.rear) {
            queue.rear = queue.rear.next;
        }
        // 3.释放被删结点的空间
        startNode.next = null;
        startNode = null;
        // 4.返回出队元素
        return data;
    }

    /**
     * 打印循环链式队列
     */
    public void print() {
        System.out.print("[");
        CLNode node = queue.next;
        while (node != queue) {
            System.out.print(node.data);
            if (node.next != queue) {
                System.out.print(", ");
            }
            node = node.next;
        }
        System.out.print("]\n");
    }
}

/**
 * 链式循环队列结点定义
 */
class CLNode {
    /**
     * 结点数据域,存储结点的数据值
     */
    int data;
    /**
     * 结点指针域,存储当前结点的后继结点的地址
     */
    CLNode next;
    /**
     * 结点指针域,即队尾指针,指向队尾结点,存储队列尾结点的地址
     */
    CLNode rear;
}

测试代码:

public class Test {
    public static void main(String[] args) throws Exception {
        Queue queue = new Queue();

        // 队列初始化
        System.out.println("队列初始化:");
        queue.init();
        queue.print();

        // 将元素入队
        System.out.println("\n将元素入队:");
        queue.enQueue(11);
        queue.print();
        queue.enQueue(22);
        queue.print();
        queue.enQueue(33);
        queue.print();
        queue.enQueue(44);
        queue.print();
        queue.enQueue(55);
        queue.print();
        queue.enQueue(66);
        queue.print();

        // 将元素出队
        System.out.println("\n将元素出队:");
        int ele;
        ele = queue.deQueue();
        System.out.println("出队元素:" + ele);
        queue.print();
        ele = queue.deQueue();
        System.out.println("出队元素:" + ele);
        queue.print();
        ele = queue.deQueue();
        System.out.println("出队元素:" + ele);
        queue.print();

    }
}

执行结果:文章来源地址https://www.toymoban.com/news/detail-719075.html

队列初始化:
[]

将元素入队:
[11]
[11, 22]
[11, 22, 33]
[11, 22, 33, 44]
[11, 22, 33, 44, 55]
[11, 22, 33, 44, 55, 66]

将元素出队:
出队元素:11
[22, 33, 44, 55, 66]
出队元素:22
[33, 44, 55, 66]
出队元素:33
[44, 55, 66]

到了这里,关于队列练习之Example002-用带头结点的循环链表表示队列,并且只设一个指针指向队尾结点,实现对应的入队列和出队列的算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 双向带头循环链表

    所属专栏:初始数据结构 博主首页:初阳785 代码托管:chuyang785 感谢大家的支持,您的点赞和关注是对我最大的支持!!! 博主也会更加的努力,创作出更优质的博文!! 关注我,关注我,关注我,重要的事情说三遍!!!!!!!! 我们之前也已经学完了单链表,并且也

    2024年02月05日
    浏览(30)
  • 带头双向循环链表

    前言:当我们想要挪动大量数据的时候,单链表的效率就很低了,比如尾插,要找到尾,通过遍历的时间复杂度最坏情况是O(N),所以我们引进结构复杂但效率高的双向带头循环链表 带头双向循环链表指得是什么呢?就是既存储了上一个节点的地址,又存储了下一个节点的地址

    2024年04月23日
    浏览(21)
  • 实现带头双向循环链表

    描述:一个节点内包含两个指针,一个指向上一个节点,另一个指向下一个节点。哨兵位指向的下一个节点为头节点,哨兵位的上一个指向尾节点。 结构优势:高效率找尾节点;高效率插入与删除;无需判断多种复杂情况,如尾节点、空节点等。 BuyListNode节点创建函数()

    2024年02月10日
    浏览(46)
  • 双向-->带头-->循环链表

    目录 一、双向带头循环链表概述 1.什么是双向带头循环链表 2.双向带头循环链表的优势 3.双向带头循环链表简图 二、双向带头循环链表的增删查改图解及代码实现 1.双向带头循环链表的头插 2.双向带头循环链表的尾插 3.双向带头循环链表的头删 4.双向带头循环链表的尾删

    2024年02月12日
    浏览(43)
  • 链表(2)——带头双向循环链表

    目录 🍁一、链表的分类 🌕1.单向或者双向 🌕2.带头或者不带头(有无哨兵) 🌕3.循环或者不循环 🌕4.无头单向非循环链表(常用) 🌕5.带头双向循环链表(常用) 🌕注意: 🍁二、双向链表的定义: 🍁三、带头双向循环链表的定义 🍁四、带头双向循环链表操作实现(

    2024年02月08日
    浏览(25)
  • “车裂”链表---双向带头循环链表

    目录 前言: 1.先看结构: 2.创建节点 3.初始化链表 4.打印链表 5.判空 6.尾插​ 7.头插​ 8.尾删​ 9.头删 10.查找与修改 修改: 11.插入---在pos之前插入 12.删除---删除pos 13.销毁 总结: 继上一章的单链表,再介绍一个更加方便的链表---双向带头循环链表: 带头即哨兵位的头节点

    2024年02月19日
    浏览(75)
  • 带头结点单链表【详细解析+完整代码】

    它是通过一组任意的储存单元来存储线性表中的数据元素。为建立线性关系,每个结点需要一个指针域以及指向下一结点的指针域。带头结点链表头节点不存储数据。 结点结构: 带头结点链表结构: 保证了每个结点都有前驱结点,因此在链表上第一个结点的操作与其他结点操

    2024年04月15日
    浏览(37)
  • 数据结构---带头双向循环链表

    什么是双向带头循环链表? 上面简单的一个非空 带头循环双向链表逻辑图 如何定义一个双向链表? 根据图和代码可以看双向链表就是单链表的每个结点中,在设置一个指向前驱节点的指针 简单认识之后,对他进行初始化(申请一个头节点,让前驱和后驱指针都指向自己) 代码

    2024年02月07日
    浏览(55)
  • 数据结构-带头双向循环链表

    前言: 链表有很多种,上一章结,我复盘了单链表,这一章节,主要针对双链表的知识点进行,整理复盘,如果将链表分类的话,有很多种,我就学习的方向考察的重点,主要针对这两种链表进行整理。 带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用

    2023年04月09日
    浏览(36)
  • 带头双向循环链表--数据结构

    😶‍🌫️😶‍🌫️😶‍🌫️😶‍🌫️Take your time ! 😶‍🌫️😶‍🌫️😶‍🌫️😶‍🌫️ 💥个人主页:🔥🔥🔥大魔王🔥🔥🔥 💥所属专栏:🔥魔王的修炼之路–数据结构🔥 如果你觉得这篇文章对你有帮助,请在文章结尾处留下你的 点赞 👍和 关注 💖,支持一

    2024年02月01日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包