当前位置: 首页 > news >正文

牧童蝉网站建设网站建设用什么框架好

牧童蝉网站建设,网站建设用什么框架好,网站有竞价的统计怎么加百度统计,网站分辨率做96是否会更好目录 1 链表的优势: 2 链表的组成: 3.一般使用结构体的形式来实现链表: 4.单向链表实现(创建,遍历,释放): 4.1代码关键点备注: 5.查找节点: 5.1.按值查找节点 5.2.按位置查找节点 5.3 …

目录

1 链表的优势:

2 链表的组成:

3.一般使用结构体的形式来实现链表:

4.单向链表实现(创建,遍历,释放):

4.1代码关键点备注:

5.查找节点:

5.1.按值查找节点

5.2.按位置查找节点

5.3 查找是否存在某个值

5.4. 查找链表中最后一个节点

5.5 查找链表中倒数第 k 个节点

6.删除节点

6.1 删除头节点

6.2删除尾节点

6.3.删除指定位置的节点

6.4.删除指定值的节点

6.5.释放整个链表


1 链表的优势:

  1. 动态大小:链表的大小可以根据需要动态调整,而数组在声明时大小固定。
  2. 插入和删除操作高效:在链表中,插入和删除操作不需要移动元素,只需修改指针即可,效率更高。
  3. 内存利用率高:链表可以根据需要分配内存,不会浪费空间。

2 链表的组成:

  1. 节点结构:链表由多个节点组成,每个节点通常包含两部分:

    • 数据域:存储实际的数据。
    • 指针域:指向下一个节点的指针(在双向链表中,还会有指向前一个节点的指针),第一个节点的指针域保存第二个节点的地址。
  2. 头指针:链表通常有一个头指针,指向链表的第一个节点。如果链表为空,头指针为NULL。

  3. 尾指针(可选):在某些实现中,链表还可能包含一个指向最后一个节点的指针,以便于在尾部插入节点时提高效率

3.一般使用结构体的形式来实现链表:

struct Node {int data;          // 数据域struct Node* next; // 指针域,指向下一个节点
};

在正式手搓单向链表前,先复习一下二级指针:

指针:一个变量,它存储另一个变量的地址。例如,Node* head 是一个指向 Node 类型的指针。

二级指针:一个指向指针的指针。比如,Node** head 表示这是一个指向 Node* 的指针,通常用于传递指针的地址,以便在函数内可以修改这个指针的值。在链表的实现中,使用二级指针来传递指向头指针的地址,这样就可以在函数内部修改头指针的值。

4.单向链表实现(创建,遍历,释放):

下面是一个代码的示例:

#include <stdio.h>
#include <stdlib.h>// 定义链表节点结构体
struct Node {int data;           // 节点数据struct Node* next;  // 指向下一个节点的指针
};// 创建链表节点并添加到链表末尾
void createNode(struct Node** head, int value) {struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); // 分配新节点内存newNode->data = value;       // 设置节点的数据newNode->next = NULL;        // 新节点的下一个指针初始化为 NULL// 检查链表是否为空if (*head == NULL) {*head = newNode;  // 如果链表为空,则将新节点设置为头节点} else {struct Node* temp = *head; // 使用 *head 访问当前头节点while (temp->next != NULL) { // 遍历链表到最后一个节点temp = temp->next;}temp->next = newNode;  // 将新节点链接到链表末尾}
}// 打印链表中的所有节点
void printList(struct Node* head) {struct Node* temp = head;  // struct Node* temp = head; 这一行定义了一个
//新的指针变量 temp,并将 head 的值(即头节点的地址)赋给它。while (temp != NULL) {printf("%d -> ", temp->data);  // 打印当前节点的数据temp = temp->next;  // 移动到下一个节点}printf("NULL\n");  // 链表结束标志
}// 释放链表内存
void freeList(struct Node** head) {struct Node* temp;while (*head != NULL) {temp = *head;          // 备份当前头节点*head = (*head)->next; // 移动头指针到下一个节点free(temp);           // 释放备份的节点内存}
}int main() {struct Node* head = NULL;  // 初始化链表头节点为空int n, value;// 输入节点的个数printf("请输入链表节点的个数: ");scanf("%d", &n);// 使用 for 循环创建链表for (int i = 0; i < n; i++) {printf("请输入第 %d 个节点的值: ", i + 1);scanf("%d", &value);createNode(&head, value);  // 通过二级指针传入头指针}// 打印链表内容printf("链表内容: ");printList(head);// 释放链表内存freeList(&head);return 0;
}

4.1代码关键点备注:

在void createNode中:

  • head 是一个指向链表 头节点 的 指针的地址。(&head)
  • 通过传入二级指针,createNode 函数可以在链表为空时直接修改头指针的值,让新节点成为链表的头节点(即 *head = newNode; 的情况)。

在void printList(struct Node* head)中:

  • head 是指向链表  头节点指针,用于从链表的第一个节点开始进行遍历。struct Node* temp = head; 这一行定义了一个新的指针变量 temp,并将 head 的值(即头节点的地址)赋给它。(head)
  • printList 函数并不修改链表的结构或内容,只是逐一访问每个节点的数据并打印。因此,只需传入一个指向头节点的普通指针,而不需要使用二级指针(不需要修改头指针的值)。

5.查找节点:

5.1.按值查找节点

  • 在链表中查找第一个数据与指定值匹配的节点,并返回该节点的指针。
  • 如果找不到该值,通常返回 NULL
struct Node* searchByValue(struct Node* head, int value) {struct Node* temp = head;while (temp != NULL) {if (temp->data == value) {return temp; // 找到匹配值的节点,返回指针}temp = temp->next; // 移动到下一个节点}return NULL; // 没有找到
}

5.2.按位置查找节点

  • 按照链表中的位置(索引)查找节点。位置通常从 0 开始,即第 0 个节点是头节点。
  • 如果位置超出链表长度,可以返回 NULL
struct Node* searchByPosition(struct Node* head, int position) {struct Node* temp = head;int currentIndex = 0;while (temp != NULL) {if (currentIndex == position) {return temp; // 找到指定位置的节点}temp = temp->next;currentIndex++;}return NULL; // 位置超出链表长度
}

5.3 查找是否存在某个值

  • 在链表中查找是否存在某个值,只返回 1(找到)或 0(未找到),而不返回节点。
int containsValue(struct Node* head, int value) {struct Node* temp = head;while (temp != NULL) {if (temp->data == value) {return 1; // 找到该值,返回 1}temp = temp->next;}return 0; // 没找到该值,返回 0
}

5.4. 查找链表中最后一个节点

  • 可以用来获取链表的尾节点。
struct Node* getLastNode(struct Node* head) {if (head == NULL) return NULL; // 链表为空struct Node* temp = head;while (temp->next != NULL) {temp = temp->next;}return temp; // 返回最后一个节点
}

5.5 查找链表中倒数第 k 个节点

  • 经典问题,常用 双指针 方法实现。用两个指针 fastslow,它们都从链表的头节点 head 出发,但 fast 会比 slow 先走 k 步。然后,让两个指针同时移动,直到 fast 到达链表的末尾。此时,slow 就刚好停在倒数第 k 个节点的位置。
  • struct Node* getKthFromEnd(struct Node* head, int k) {struct Node *fast = head, *slow = head;// 让 fast 指针先走 k 步for (int i = 0; i < k; i++) {if (fast == NULL) return NULL; // 链表长度小于 kfast = fast->next;}// 同时移动 fast 和 slow 指针,直到 fast 到达链表末尾while (fast != NULL) {fast = fast->next;slow = slow->next;}return slow; // slow 指针就是倒数第 k 个节点
    }
    

    6.删除节点

6.1 删除头节点

void deleteHead(struct Node** head) {if (*head == NULL) return; // 链表为空,无法删除struct Node* temp = *head; // 备份头节点*head = (*head)->next;     // 更新头节点为下一个节点free(temp);                // 释放备份的头节点内存
}

6.2删除尾节点

删除链表的最后一个节点。需要遍历链表,找到倒数第二个节点并将其 next 指针设为 NULL

void deleteTail(struct Node** head) {if (*head == NULL) return; // 链表为空,无法删除if ((*head)->next == NULL) { // 如果只有一个节点free(*head);*head = NULL; // 更新头指针为 NULLreturn;}struct Node* temp = *head;while (temp->next->next != NULL) { // 遍历到倒数第二个节点temp = temp->next;}free(temp->next); // 释放最后一个节点temp->next = NULL; // 将倒数第二个节点的 next 设为 NULL
}

1 -> 2 -> 3 -> NULL

在执行删除尾节点的操作时:

  • temp 会遍历到节点 2(倒数第二个节点),temp->next 会指向节点 3(最后一个节点)。
  • 当我们执行 free(temp->next);,节点 3 被释放。
  • 然后执行 temp->next = NULL;,使得节点 2 变成链表的新尾节点,链表现在变为:

1 -> 2 -> NULL

6.3.删除指定位置的节点

根据给定的位置删除节点。

void deleteAtPosition(struct Node** head, int position) {if (*head == NULL) return; // 链表为空,无法删除if (position == 0) { // 如果要删除的是头节点deleteHead(head);return;}struct Node* temp = *head;for (int i = 0; i < position - 1; i++) {if (temp == NULL || temp->next == NULL) {printf("位置超出链表长度\n");return; // 位置超出链表长度,无法删除}temp = temp->next; // 遍历到要删除节点的前一个节点}struct Node* nodeToDelete = temp->next; // 要删除的节点if (nodeToDelete == NULL) return; // 如果没有下一个节点,无法删除temp->next = nodeToDelete->next; // 将前一个节点的 next 指向要删除节点的下一个节点free(nodeToDelete); // 释放要删除的节点内存
}

6.4.删除指定值的节点

删除链表中第一个值匹配指定值的节点

void deleteByValue(struct Node** head, int value) {if (*head == NULL) return; // 链表为空,无法删除struct Node* temp = *head;// 如果头节点的值就是要删除的值if (temp->data == value) {deleteHead(head);return;}// 遍历链表查找匹配的节点while (temp->next != NULL) {if (temp->next->data == value) { // 找到匹配的节点struct Node* nodeToDelete = temp->next; // 备份要删除的节点temp->next = nodeToDelete->next; // 链接前一个节点与后一个节点free(nodeToDelete); // 释放要删除的节点内存return; // 删除完毕,退出函数}temp = temp->next; // 移动到下一个节点}
}

6.5.释放整个链表

如果需要删除整个链表,释放所有节点内存。

void freeList(struct Node** head) {struct Node* temp;while (*head != NULL) {temp = *head; // 备份当前头节点*head = (*head)->next; // 移动头指针到下一个节点free(temp); // 释放备份的节点内存}
}

http://www.yayakq.cn/news/14230/

相关文章:

  • 宁波哪里有网站建设高端的网站备案可以强制撤销吗
  • 网站建设培训速成网站子站点是什么意思
  • 网页网站建设的步骤流程图网页设计培训包就业
  • 临淄做网站wordpress 媒体库外链
  • 商会网站建设招标方案微信公众号网站开发本地调试
  • 网站快速上排名方法WordPress 长文 阅读
  • 做网站充值系统wordpress添加flash游戏
  • 上海金工建设集团有限公司网站wordpress4.3
  • 海淀教育人才网站网站的功能包括哪些
  • 用网站做自我介绍ppt秀色直播app软件大全
  • 矿山建设工程公司网站怎样购买网站域名
  • 广州商城网站开发群辉安装wordpress
  • cms网站怎么制作网站制作预算
  • 广东省建设监理协会官方网站微信域名防封跳转系统
  • 随州网站建设推荐safari浏览器
  • 怎么用链接进自己做的网站东莞网络营销网络推广软件
  • 开网站平台需要多少钱建筑专业人才招聘网
  • 多个网站建站软考证书有用吗张雪峰
  • 公司网站的设计规划网页版免费
  • 诸暨 外贸网站建设怎么登陆网站后台管理系统
  • 中国建设银行金华分行网站设计师怎么做响应式网站
  • 美食网站建设实施方案网站备案注销查询
  • 漯河网站推广哪家好青岛php网站建设
  • ae成品免费下载网站网站建设经销商
  • 外贸网站样式做网站专用软件
  • 营销网站建设专业团队在线服务运维系统
  • 电子商务网站的设计网站开发与服务合同范本
  • 超链接网站怎么做济南网络广播电视台
  • 黑河城乡建设局网站做本地地旅游网站
  • 网页布局的目的英文seo 文章发布类网站