C数据结构—链表应用
链表应用
链表像数据库一样可以增删改查,我们现在写一个简单的需求练习一下:
李华要登记全国名字和他一样的人的信息,看看有多少人和他一样要给外国朋友写信,现在,李华想请你帮他写一个程序,统计这些人的信息,并给其中的一些人写信。
这些人的信息会由李华提供给你。
李华思维跳脱,有可能突然想给某个人写信,需要你给他提供这个人的邮箱地址(超过50个字符),也有可能李华在看到回复后突然不想再给某人写信了,然后要求你将这个人从记录中删除。有时候李华会发现某个人的邮箱更新了,以至于之前的邮箱收不到消息,所以他会要求你更改某人的邮箱。
李华会给你一些指令代表不同的操作:
插入一个人的邮箱到第n个位置:
i n XXX@XXX.XXX
查询第n个人的邮箱:
q n
删除第n个人的邮箱:
d n
修改第n个人的邮箱为YYY@YYY.YYY:
m n YYY@YYY.YYY
李华会用这些简单的指令和你交流,同时他也需要一些反馈:
插入或删除后你需要告诉他操作成功:
copy
查询或修改后你要告诉他现在这个人的邮箱是什么:
copy AAA@AAA.AAA
最后,李华会告诉你,你(的程序)可以休息了:
e
现在我们来设计这个程序
用链表存储数据的话也很简单:
#define MAX_SIZE 50 #define BUFFER 5 typedef struct ListNode { char mail[MAX_SIZE + BUFFER * 2]; struct ListNode* nxt; } ListNode; typedef struct List { struct ListNode* head; int length; } List;
这里将整个链表存为一整个对象。
各种操作:
// 插入 int insertListNode(List* l, int index, ListNode* ln) { if (index > l->length) return 0; ListNode* curNode = l->head; int i = 0; for (i = 0; i < index; ++i) { curNode = curNode->nxt; } ln->nxt = curNode->nxt; curNode->nxt = ln; l->length += 1; return 1; } // 寻找 ListNode* searchNode(List* l, int index) { if (index > l->length) return NULL; ListNode* curNode = l->head; int i = 0; for (i = 0; i < index; ++i) { curNode = curNode->nxt; } return curNode->nxt; } // 删除 int deleteListNode(List* l, int index) { if (index > l->length) return 0; ListNode* curNode = l->head; int i = 0; for (i = 0; i < index; ++i) { curNode = curNode->nxt; } ListNode* tmp = curNode->nxt; curNode->nxt = tmp->nxt; free(tmp); return 1; } // 修改 ListNode* modifyListNode(List* l, int index, const char* data) { ListNode* ln = searchNode(l, index); if (ln == NULL) return NULL; strncpy(ln->mail, data, MAX_SIZE + BUFFER); return ln; } // 删除整个链表 void destroyList(ListNode *ln) { if (ln->nxt == NULL) return; destroyList(ln->nxt); free(ln->nxt); ln->nxt = NULL; return; }
全部代码:
#include <stdio.h> #include <string.h> #include <stdlib.h> #define MAX_SIZE 50 #define BUFFER 5 typedef struct ListNode { char mail[MAX_SIZE + BUFFER * 2]; struct ListNode* nxt; } ListNode; typedef struct List { struct ListNode* head; int length; } List; ListNode* createListNode(const char *data) { ListNode* ln = (ListNode*)malloc(sizeof(ListNode)); strncpy(ln->mail, data, MAX_SIZE + BUFFER); ln->nxt = NULL; return ln; } void initList(List* l) { l->head = createListNode(""); l->length = 0; return; } // 插入 int insertListNode(List* l, int index, ListNode* ln) { if (index > l->length) return 0; ListNode* curNode = l->head; int i = 0; for (i = 0; i < index; ++i) { curNode = curNode->nxt; } ln->nxt = curNode->nxt; curNode->nxt = ln; l->length += 1; return 1; } // 寻找 ListNode* searchNode(List* l, int index) { if (index > l->length) return NULL; ListNode* curNode = l->head; int i = 0; for (i = 0; i < index; ++i) { curNode = curNode->nxt; } return curNode->nxt; } // 删除 int deleteListNode(List* l, int index) { if (index > l->length) return 0; ListNode* curNode = l->head; int i = 0; for (i = 0; i < index; ++i) { curNode = curNode->nxt; } ListNode* tmp = curNode->nxt; curNode->nxt = tmp->nxt; free(tmp); return 1; } // 修改 ListNode* modifyListNode(List* l, int index, const char* data) { ListNode* ln = searchNode(l, index); if (ln == NULL) return NULL; strncpy(ln->mail, data, MAX_SIZE + BUFFER); return ln; } // 删除整个链表 void destroyList(ListNode *ln) { if (ln->nxt == NULL) return; destroyList(ln->nxt); free(ln->nxt); ln->nxt = NULL; return; } int main(void) { List l; initList(&l); while (1) { char c; c = getchar(); if (c == 'e') break; int index; char mail[MAX_SIZE + BUFFER * 2]; switch (c) { case 'i': { scanf("%d %s", &index, mail); int msg = insertListNode(&l, index, createListNode(mail)); if (msg) puts("copy"); else puts("wrong"); break; } case 'q': { scanf("%d", &index); ListNode* ln = searchNode(&l, index); if (ln == NULL) puts("wrong"); else printf("copy %s\n", ln->mail); break; } case 'd': { scanf("%d", &index); int msg = deleteListNode(&l, index); if (msg) puts("copy"); else puts("wrong"); break; } case 'm': { scanf("%d %s", &index, mail); ListNode* ln = modifyListNode(&l, index, mail); if (ln == NULL) puts("wrong"); else printf("copy %s\n", ln->mail); break; } } } destroyList(l.head); return 0; }