队列练习之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模板网!

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

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

相关文章

  • 带头双向循环链表

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

    2024年04月23日
    浏览(30)
  • 双向-->带头-->循环链表

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

    2024年02月12日
    浏览(54)
  • 实现带头双向循环链表

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

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

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

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

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

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

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

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

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

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

    在创建带头双向循环链表的节点中比之前单链表节点的创建多了一个struct ListNode* prev;结构体指针,目的在与存储前一个节点的地址,便于将整个链表连在一起。 动态申请内存结点,函数返回的是一个指针类型,用malloc开辟一个LTNode大小的空间,并用node指向这个空间,再判断

    2024年02月09日
    浏览(42)
  • 【数据结构】带头双向循环链表

      🧑‍🎓 个人主页:简 料   🏆 所属专栏:C++   🏆 个人社区:越努力越幸运社区   🏆 简       介: 简料简料,简单有料~在校大学生一枚,专注C/C++/GO的干货分享,立志成为您的好帮手 ~ C/C++学习路线 (点击解锁) ❤️ C语言阶段(已结束) ❤️ 数据结构与算法(ing) ❤

    2024年01月16日
    浏览(78)
  • 数据结构---带头双向循环链表

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

    2024年02月07日
    浏览(69)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包