本文共 6766 字,大约阅读时间需要 22 分钟。
链表是一种常用的数据结构,具有灵活性和效率优势。本文将详细介绍链表的操作方法,包括初始化、插入、删除、查找、逆序等功能的实现。
InitLinkList 函数用于初始化一个空链表。该函数分配内存空间,创建头结点,并将头结点的 next 指针设置为 NULL。
Status InitLinkList(LinkList &linkList) { linkList = (LinkList)malloc(sizeof(LinkNode)); if (!linkList) exit(OVERFLOW); linkList->next = NULL; return OK;} LengthOfLinkList 函数用于获取链表的长度。通过遍历链表从头结点开始,逐个访问 next 指针,直到遇到 NULL 为止,统计访问次数即为链表长度。
int LengthOfLinkList(LinkList linkList) { LinkNode *p = linkList->next; int length = 0; while (p != NULL) { length++; p = p->next; } return length;} 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; }} 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;} 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; }} 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; }} 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; }} 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;} PrintLinkList 函数用于打印链表中的所有节点数据。
void PrintLinkList(LinkList linkList) { LinkNode *p = linkList; cout << "头结点 → "; while (p->next) { p = p->next; cout << p->data << " → "; } cout << "NULL" << endl;} 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;} 以下是一个完整的链表操作示例:
#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/