博客
关于我
链表的定义
阅读量:582 次
发布时间:2019-03-11

本文共 6766 字,大约阅读时间需要 22 分钟。

链表操作手册:C语言链表函数实现

链表是一种常用的数据结构,具有灵活性和效率优势。本文将详细介绍链表的操作方法,包括初始化、插入、删除、查找、逆序等功能的实现。

1. 链表的基本操作

1.1 初始化链表

InitLinkList 函数用于初始化一个空链表。该函数分配内存空间,创建头结点,并将头结点的 next 指针设置为 NULL

Status InitLinkList(LinkList &linkList) {    linkList = (LinkList)malloc(sizeof(LinkNode));    if (!linkList) exit(OVERFLOW);    linkList->next = NULL;    return OK;}

1.2 链表长度查询

LengthOfLinkList 函数用于获取链表的长度。通过遍历链表从头结点开始,逐个访问 next 指针,直到遇到 NULL 为止,统计访问次数即为链表长度。

int LengthOfLinkList(LinkList linkList) {    LinkNode *p = linkList->next;    int length = 0;    while (p != NULL) {        length++;        p = p->next;    }    return length;}

1.3 查找节点位置

LocationInOrder 函数用于查找链表中指定顺序的节点地址。函数通过遍历链表,逐步移动 cursor 指针,直到找到目标节点或确定节点不存在。

Status LocationInOrder(LinkList linkList, int order, LinkNode *&p_linkNode) {    if (0 <= order) {        LinkNode *cursor = linkList;        int index = 0;        while (index < order && cursor) {            cursor = cursor->next;            index++;        }        if (!cursor) {            return ERROR;        } else {            p_linkNode = cursor;            return OK;        }    } else {        return ERROR;    }}

2. 链表元素操作

2.1 插入节点

InsertLinkList 函数用于在链表头部插入新节点。新节点的 next 指针指向原链表的头节点,原链表的头节点的 next 指针指向新节点。

Status InsertLinkList(LinkList &linkList, ElemType data) {    LinkNode *p_dataNode = (LinkNode *)malloc(sizeof(LinkNode));    if (!p_dataNode) return ERROR;    p_dataNode->data = data;    p_dataNode->next = linkList->next;    linkList->next = p_dataNode;    return OK;}

2.2 插入在指定位置

InsertLinkList 函数用于在指定序号位置插入新节点。首先查找指定位置的前驱节点,然后插入新节点。

Status InsertLinkList(LinkList &linkList, int order, ElemType data) {    if (LocationInOrder(linkList, order - 1, p_preOfOrder) == OK && p_preOfOrder->next) {        LinkNode *p_dataNode = (LinkNode *)malloc(sizeof(LinkNode));        if (!p_dataNode) return OVERFLOW;        p_dataNode->data = data;        p_dataNode->next = p_preOfOrder->next;        p_preOfOrder->next = p_dataNode;        return OK;    } else {        return ERROR;    }}

2.3 删除节点

DeleteLinkNode 函数用于删除指定序号位置的节点。首先查找指定位置的前驱节点,然后删除该节点。

Status DeleteLinkNode(LinkList &linkList, int order) {    if (LocationInOrder(linkList, order - 1, p_preOfOrder) == OK && p_preOfOrder->next) {        LinkNode *p_del = p_preOfOrder->next;        p_preOfOrder->next = p_del->next;        free(p_del);        return OK;    } else {        return ERROR;    }}

3. 链表操作扩展

3.1 链表逆序

ReverseLinkList 函数用于将链表逆序。首先查找链表的第二个节点,然后通过头插法逐步将节点取出并插入到头部。

Status ReverseLinkList(LinkList &linkList) {    LinkNode *p_second = NULL;    if (LocationInOrder(linkList, 2, p_second) == OK) {        LinkNode *preCursor, *cursor;        preCursor = cursor = p_second;        while (preCursor) {            preCursor->next = linkList->next;            linkList->next = preCursor;            preCursor = cursor;            cursor = cursor->next;        }        return OK;    } else {        return ERROR;    }}

3.2 链表合并

MergeLinkList 函数用于将两个链表合并。合并规则是按照元素值大小进行比较,逐步将节点插入到合并后的链表中。

LinkList MergeLinkList(LinkList &linkList_dest, LinkList &linkList_source) {    LinkNode *p_dest = linkList_dest->next;    LinkNode *p_source = linkList_source->next;    LinkNode *p_tmp = linkList_dest;    while (p_dest && p_source) {        if (p_dest->data <= p_source->data) {            p_tmp->next = p_dest;            p_tmp = p_dest;            p_dest = p_dest->next;        } else {            p_tmp->next = p_source;            p_tmp = p_source;            p_source = p_source->next;        }    }    p_tmp->next = p_dest ? p_dest : p_source;    free(linkList_source);    return linkList_dest;}

4. 链表的输入输出

4.1 打印链表

PrintLinkList 函数用于打印链表中的所有节点数据。

void PrintLinkList(LinkList linkList) {    LinkNode *p = linkList;    cout << "头结点 → ";    while (p->next) {        p = p->next;        cout << p->data << " → ";    }    cout << "NULL" << endl;}

4.2 读取输入并初始化链表

InputLinkNodes 函数用于读取用户输入并将数据节点插入链表中。

int InputLinkNodes(LinkList &linkList) {    char finishFlag = '\n';    int length = 0;    cout << "请输入一组" << typeid(ElemType).name() << "序列(回车结束输入):";    do {        ElemType data;        cin >> data;        InsertLinkList(linkList, ++length, data);        finishFlag = getchar();    } while (finishFlag != '\n');    return length;}

5. 完整示例

以下是一个完整的链表操作示例:

#include 
#include "../../全局定义/预定义常量和类型/预定义常量和类型.cpp"#include "../../全局定义/Compare函数的定义/Compare函数的定义.cpp"using namespace std;template
struct LinkNode { ElemType data; struct LinkNode
* next;};#define LinkList LinkNode
*Status InitLinkList(LinkList &linkList) { linkList = (LinkList)malloc(sizeof(LinkNode
)); if (!linkList) exit(OVERFLOW); linkList->next = NULL; return OK;}int LengthOfLinkList(LinkList linkList) { LinkNode
*p = linkList->next; int length = 0; while (p != NULL) { length++; p = p->next; } return length;}Status LocationInOrder(LinkList linkList, int order, LinkNode
*&p_linkNode) { if (0 <= order) { LinkNode
*cursor = linkList; int index = 0; while (index < order && cursor) { cursor = cursor->next; index++; } if (!cursor) { return ERROR; } else { p_linkNode = cursor; return OK; } } else { return ERROR; }}Status DeleteLinkNode(LinkList &linkList, int order) { if (LocationInOrder(linkList, order - 1, p_preOfOrder) == OK && p_preOfOrder->next) { LinkNode
*p_del = p_preOfOrder->next; p_preOfOrder->next = p_del->next; free(p_del); return OK; } else { return ERROR; }}int main() { // 初始化链表 LinkList linkList; InitLinkList(linkList); // 读取输入并初始化链表 int length = InputLinkNodes(linkList); cout << "linkList的长度为:" << length << endl; cout << "linkList的元素有:"; PrintLinkList(linkList); // 删除第1个节点 int order_del = 1; DeleteLinkNode(linkList, order_del); cout << "删除第" << order_del << "个节点之后:"; PrintLinkList(linkList); // 删除第5个节点 order_del = 5; DeleteLinkNode(linkList, order_del); cout << "删除第" << order_del << "个节点之后:"; PrintLinkList(linkList); // 删除第3个节点 order_del = 3; DeleteLinkNode(linkList, order_del); cout << "删除第" << order_del << "个节点之后:"; PrintLinkList(linkList); // 链表逆序输出 ReverseLinkList(linkList); cout << "linkList逆序输出: "; PrintLinkList(linkList); // 合并链表 LinkList linkList_source; InitLinkList(linkList_source); InsertLinkList(linkList_source, 3); InsertLinkList(linkList_source, 2); InsertLinkList(linkList_source, 1); cout << "linkList\t:\t"; PrintLinkList(linkList); cout << "linkList_source\t:\t"; PrintLinkList(linkList_source); cout << "合并后linkList\t:\t"; InsertLinkList(linkList, 2, linkList_source); PrintLinkList(linkList); // 测试相对位置查找 LinkNode
*p = NULL; LocationInOrder(linkList, 2, p); cout << "第2个位置的元素为:" << p->data << endl; cout << "第1个" << p->data << "的位置为:"; int (*compare)(ElemType, ElemType) = Equal; int location = LocationOfLinkNode(linkList, p->data, p_linkNode_2, compare); cout << location << endl; return 0;}

转载地址:http://rhwtz.baihongyu.com/

你可能感兴趣的文章
NYOJ127星际之门(一)
查看>>
nyoj58 最少步数
查看>>
N皇后问题
查看>>
N皇后问题
查看>>
n种方式教你用python读写excel等数据文件
查看>>
OAuth 2.0 MAC Tokens
查看>>
OAuth 及 移动端鉴权调研
查看>>
OAuth2 + Gateway统一认证一步步实现(公司项目能直接使用),密码模式&授权码模式
查看>>
OAuth2 Provider 项目常见问题解决方案
查看>>
OAuth2 vs JWT,到底怎么选?
查看>>
Vue.js 学习总结(14)—— Vue3 为什么推荐使用 ref 而不是 reactive
查看>>
oauth2-shiro 添加 redis 实现版本
查看>>
OAuth2.0_JWT令牌-生成令牌和校验令牌_Spring Security OAuth2.0认证授权---springcloud工作笔记148
查看>>
OAuth2.0_JWT令牌介绍_Spring Security OAuth2.0认证授权---springcloud工作笔记147
查看>>
OAuth2.0_介绍_Spring Security OAuth2.0认证授权---springcloud工作笔记137
查看>>
OAuth2.0_完善环境配置_把资源微服务客户端信息_授权码存入到数据库_Spring Security OAuth2.0认证授权---springcloud工作笔记149
查看>>
OAuth2.0_授权服务配置_Spring Security OAuth2.0认证授权---springcloud工作笔记140
查看>>
OAuth2.0_授权服务配置_三项内容_Spring Security OAuth2.0认证授权---springcloud工作笔记141
查看>>
OAuth2.0_授权服务配置_令牌服务和令牌端点配置_Spring Security OAuth2.0认证授权---springcloud工作笔记143
查看>>
OAuth2.0_授权服务配置_客户端详情配置_Spring Security OAuth2.0认证授权---springcloud工作笔记142
查看>>