博客
关于我
链表的定义
阅读量: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/

你可能感兴趣的文章
Netty WebSocket客户端
查看>>
Netty工作笔记0011---Channel应用案例2
查看>>
Netty工作笔记0014---Buffer类型化和只读
查看>>
Netty工作笔记0050---Netty核心模块1
查看>>
Netty工作笔记0084---通过自定义协议解决粘包拆包问题2
查看>>
Netty常见组件二
查看>>
netty底层源码探究:启动流程;EventLoop中的selector、线程、任务队列;监听处理accept、read事件流程;
查看>>
Netty核心模块组件
查看>>
Netty框架的服务端开发中创建EventLoopGroup对象时线程数量源码解析
查看>>
Netty源码—2.Reactor线程模型一
查看>>
Netty源码—4.客户端接入流程一
查看>>
Netty源码—4.客户端接入流程二
查看>>
Netty源码—5.Pipeline和Handler一
查看>>
Netty源码—6.ByteBuf原理二
查看>>
Netty源码—7.ByteBuf原理三
查看>>
Netty源码—7.ByteBuf原理四
查看>>
Netty源码—8.编解码原理二
查看>>
Netty源码解读
查看>>
Netty的Socket编程详解-搭建服务端与客户端并进行数据传输
查看>>
Netty相关
查看>>