zoukankan      html  css  js  c++  java
  • 第十周知识总结

    1.完成了循环双向链结表以及打印出反转循环双向链结表

    部分代码

    // 初始化双向链结表 L。
    void initial(DList *L) {
    L->head = NULL; // 将双向链结表的头节点指针设为空值。
    L->tail = NULL; // 将双向链结表的尾节点指针设为空值。
    }

    // 取得双向链结表 L 的元素个数。
    int getSize(DList L) {
    Link current = L.head; // 节点指针。
    int size = 0; // 线性表个数初始值设为 0.

    if (current==NULL) return size; // 如果线性表为空,则元素个数为 0.

    do { // 加一个节点计数。
    size++; // 个数加 1。
    current = current->next; // 下一个节点。
    } while (current!=L.head); // 如果不是尾节点,继续搜寻。
    return size; // 线性表 L 的元素个数。
    }

    // 取出循环双向链结表的第 i 个元素, 返回该元素的值。
    // 若 inx<0, 向左移动;若 inx>0, 向右移动。
    // 若 |inx| 大于双向链结表的元素个数,则循环重复计数。
    ElemType getElem(DList L, int inx) {
    Link current = L.head; // 头节点指针。
    int i; // 循环变量。

    if (current==NULL) return -1; // 如果线性表为空,则无此元素。

    // 循环线性表,如果 inx>size, 会重复 L 的头节点。
    for (i=0; i<abs(inx); i++)
    if (inx>0) current = current->next; // 往右移到下一个元素。
    else current = current->prev; // 往左移到前一个元素。
    return current->elem; // 返回节点的元素值。
    }

    // 搜寻循环双向链结表的元素。若成功,返回元素位置;否则,返回 -1。
    int search(DList L, ElemType e) {
    Link current = L.head; // 头节点指针。
    int position=0; // 元素位置,设定初始值为 0。

    if (current==NULL) return -1; // 如果循环双向链结表为空,则无此元素。

    do { // 循环双向链结表不是空的,至少做一次。
    if (current->elem==e) return position; // 搜寻成功,返回元素 e 的位置。
    else if (current->elem<e) { // 还有其它节点,继续搜寻。
    position++; // 位置加 1。
    current = current->next; // 移到下一个节点。
    }
    else return -1; // 节点的值已超过,搜寻失败。
    } while (current!=L.head); // 若回到头节点,则停止循环。
    return -1; // 已经超过循环双向链结表的最后一个节点,搜寻失败。
    }

    // 将一个元素插入到循环双向链结表,返回该元素的位置。
    int insert(DList *L, ElemType e) {
    Link current = L->head; // 指向头节点。
    Link previous = L->tail; // 指向尾节点。
    Link newNode; // 新节点的指针。
    int size = getSize(*L); // 循环双向链结表的元素个数。
    int position=0; // 目前节点位置。
    if (current==NULL) { // Case 1:当循环双向链结表为空时。
    newNode = (Link) malloc(sizeof(Node)); // 要求一个新节点的内存。
    newNode->elem = e; // 复制节点的数据。
    newNode->prev = newNode; // 循环双向链结表只有一个节点,prev 指向自己。
    newNode->next = newNode; // 循环双向链结表只有一个节点,next 指向自己。
    L->head = newNode; // 设定循环双向链结表只头节点。
    L->tail = newNode; // 设定循环双向链结表只尾节点。
    return position; // 头节点的位置为 0。
    }

    for (position=0; position<size; position++) { // 寻找插入位置。
    if (current->elem>=e) break; // 找到第一个元素大于或等于 e 的节点。
    previous = current; // 下一个 previous。
    current = current->next; // 下一个 current。
    }
    if (position==0) { // Cases 2: 插入头节点的 current 之前。
    newNode = (Link) malloc(sizeof(Node)); // 要求一个新节点的内存。
    newNode->elem = e; // 复制目前节点的数据。
    newNode->prev = previous; // 设定新节点的 prev 指针。
    previous->next = newNode; // 将前一节点的 next 指针指向新节点。
    newNode->next = current; // 设定新节点的 next 指针。
    current->prev = newNode; // 将现节点的 prev 指针指向新节点。
    L->head = newNode; // 更新头节点。
    return position; // 返回位置。
    }
    else if (position<size) { // Cases 3: 插入中间节点的 current 之前。
    newNode = (Link) malloc(sizeof(Node)); // 要求一个新节点的内存。
    newNode->elem = e; // 复制目前节点的数据。
    newNode->prev = previous; // 设定新节点的 prev 指针。
    previous->next = newNode; // 将前一节点的 next 指针指向新节点。
    newNode->next = current; // 设定新节点的 next 指针。
    current->prev = newNode; // 将现节点的 prev 指针指向新节点。
    return position; // 返回位置。
    }

    // Case 4:插入到循环双向链结表的尾节点之后,成为新的尾节点。
    newNode = (Link) malloc(sizeof(Node)); // 要求一个新节点的内存。
    newNode->elem = e; // 复制目前节点的数据。
    newNode->prev = previous; // 设定新节点的 prev 指针。
    previous->next = newNode; // 将前一节点的 next 指针指向新节点。
    newNode->next = current; // 设定新节点的 next 指针。
    current->prev = newNode; // 将现节点的 prev 指针指向新节点。
    L->tail = newNode; // 插入的节点成为新的尾节点。
    return position; // 返回位置。
    }

    // 从循环双向链结表删除一个元素。若成功,返回该元素原来的位置;
    // 否则,返回 -1。
    int delete(DList *L, ElemType e) {
    Link current = L->head; // 指向头节点。
    Link previous = L->tail; // 指向尾节点。
    int position = 0; // 目前节点位置。

    if (current==NULL) return -1; // 若循环双向链结表为空,删除失败。

    do { // 当循环双向链结表还有节点。
    if (current->elem==e) { // 找到要删除的节点。
    if (position==0) { // 删除的节点是头节点。
    if (current->next==current) { // 循环双向链结表只有一个节点。
    L->head = NULL; // 将头节点清空。
    L->tail = NULL; // 将尾节点清空。
    }
    else {
    previous->next = current->next; // 修改前一个节点的 next 指针。
    current->next->prev = previous; // 修改下一个节点的 prev 指针。
    L->head = current->next; // 更新头节点。
    }
    free(current); // 释放删除的节点。
    return position; // 返回删除节点的原来位置。
    }
    else {
    if (current->next==L->head) // 删除的是尾节点。
    L->tail = previous; // 更新尾节点。
    previous->next = current->next; // 修改前一个节点的 next 指针。
    current->next->prev = previous; // 修改下一个节点的 prev 指针。
    free(current); // 释放删除的节点。
    return position; // 返回删除节点的原来位置。
    }
    }
    else if (current->elem<e) { // 检查下一个节点。
    previous = current; // 将目前的节点设为前一个节点。
    current = current->next; // 将下一个节点设为下一步骤的目前节点。
    position++; // 位置加 1。
    }
    else return -1; // 目前节点数据已超过删除的值;删除失败。
    } while (current!=L->head); // 若还没回到头节点,继续检查。

    return -1; // current 回到头节点,删除失败。
    }

    // 将循环双向链结表清空。
    void clear(DList *L) {
    Link current = L->head; // 指向目前的节点。
    Link previous; // 前一个节点。

    while (current->next!=L->head) { // 不是尾节点。
    previous = current; // 目前的节点。
    current = current->next; // 下一个节点。
    free(previous); // 释放目前的节点。
    }
    free(current); // 释放尾节点。
    L->head = NULL; // 将循环双向链结表的头节点设为空。
    L->tail = NULL; // 将循环双向链结表设尾节点设为空。
    }

    // 檢查循环双向链结表是否為空表。若是空,返回 1;否则,返回 0。
    int is_empty(DList L) {
    return L.head==NULL; // 若 L 的头节点为空,返回 1,否则,返回 0。
    }
    // 打印循环双向链结表元素。
    void printlst(DList L) {
    Link current = L.head; // 指向目前的节点。
    int position = 0; // 目前节点的位置。

    printf("线性表元素个数:%3d 元素 ", getSize(L));

    if (current!=NULL) { // 循环双向链结表不是空的,开始打印。
    while (current->next!=L.head) { // 还有节点要打印。
    printf("%3d ", current->elem); // 打印节点数据。
    if ((position+1)%20==0) printf(" "); // 满 20 个元素,打印换行。
    current = current->next; // 移到下一个节点。
    position++; // 下一个位置。
    }
    printf("%3d ", current->elem); // 打印尾节点数据和换行。
    }
    printf(" "); // 打印一个换行。
    }

     2.关于循环双向链结表的思维导图

    删除思维导图如下

  • 相关阅读:
    springboot运行时该注意的地方
    建立第一个SpringBoot小列子(碰到的错误)
    mysql建表基本语法
    两层c:forEach循环嵌套
    git-------基础知识(本地推送项目版本---github上)
    《生活的邀请函》___ 奥雷阿
    输入路径(包括盘符),打印层级目录(隐藏文件也会打印出来)
    输入两个文件夹路径,把其中一个文件夹中(包含内容)拷贝到另一个文件夹中
    用java实现歌曲串烧高速版(SequenceInputStream的使用)
    Java中InputStream装饰器模式的大家族
  • 原文地址:https://www.cnblogs.com/mju3197103150/p/12864150.html
Copyright © 2011-2022 走看看