有关链表的c语言程序代码,动态链表的增删改查,打印销毁等基本操作及代码模块化(完整C语言代码!)...

首先介绍一些链表的基本知识,然后通过程序实现链表操作的基本功能,增删改查,打印等等操作,并模块化来深化这部分知识点。

链表基础知识

1、由一张内存图展开

0818b9ca8b590ca3270a3433284dd417.png

(1)链表有一个“头指针”变量,如果不提供“头指针”,整个链表都无法访问;

(2)链表的每个元素成为“结点”,每个结点包括数据和下一个结点的地址。末尾的结点地址部分为NULL(空地址);

(3)链表中个元素在内存中的地址可以是不连续的;

2、链表的建立

(1)静态链表:所有结点在程序中定义的,不是临时开辟的,也不能用完后释放;

(2)动态链表:在程序执行过程中从无到有地建立起一个链表,即一个一个地开辟结点和输入各结点数据,并建立起前后相链的关系。

3、链表的基本操作

写这个代码的时候,中间因为一个while写成了if真是最后测试一直错误,真是醉了!!!奉上完整代码。有错的地方请指正~测试下来是没错的。

#include

#include

typedef int Datatype; //如果存其他类型的数据可以在此处直接修改

typedef struct node {

Datatype data;

struct node *next;

}Node;

//创建结点

Node* creatNode(Datatype data) {

Node* p = NULL;

p = (Node*)malloc(sizeof(Datatype)); //申请内存

if (p == NULL) { //安全检查

return NULL;

}

p->data = data; //赋值

p->next = NULL;

return p;

}

//打印链表

void printList(Node* head) {

Node* p = head;

if (head == NULL) {

return;

}

while(p != NULL) {

printf("%d\n",p->data);

p = p->next;

}

return;

}

//在一个结点后插入新结点

int insertNodeBehind(Node* p,Node* pnew) {

if (p == NULL || pnew == NULL) {

return -1;

}

if (p->next != NULL) {

pnew->next = p->next;

p->next = pnew;

}

else {

p->next = pnew;

}

/*其实此处直接写

pnew->next = p->next;

p->next = pnew;

就可以了,因为若p->next = NULL则pnew->next = NULL*/

return 0;

}

//结点后插入一个数据

int insertDataBehind(Node *p,Datatype data) { Node* pnew = NULL; if (p == NULL) { return -1; }

pnew = creatNode(data);

insertNodeBehind(p,pnew);

return 0;

}

//返回最后末尾结点的地址

Node* findListTail(Node* phead) {

if (phead == NULL) {

return NULL;

}

while (phead->next != NULL) {

phead = phead->next;

}

return phead;

}

//插入数据到链表的末尾,**是因为可能会涉及修改头指针,在没有结点的情况下

int listInsertDataAtTail(Node** phead,Datatype data) {

Node *p = NULL;

if (phead == NULL) {

return -1;

}

if (*phead == NULL) {

*phead = creatNode(data);

return 0;

}

p = findListTail(*phead);

insertDataBehind(p,data);

return 0;

}

//删除后一个结点

int deleteNodeBehind(Node* p) {

Node* temp = NULL;

if (p == NULL) {

return -1;

}

if (p->next == NULL) {

return 1;

}

temp = p->next;

p->next = p->next->next;

free(temp);

return 0;

}

//返回数据为data的结点的地址

Node* findNode(Node* head,Datatype data) {

Node* p = NULL;

if (head == NULL) {

return NULL;

}

p = head;

while (p->data != data) {

if (p->next != NULL) {

p = p->next;

}

else {

return NULL; //没找到该数据为data的结点

}

}

return p;

}

//改数据

int listChangeData(Node* head,Datatype oldData,Datatype newData) {

Node* p = NULL;

if (head == NULL) {

return -1;

}

p = findNode(head, oldData);

p->data = newData;

return 0;

}

//返回数据为data的结点的前一个结点的地址

Node* findPrevNode(Node *head,Datatype data) {

Node* p = NULL;

if (head == NULL) {

return NULL;

}

p = head;

while (p->next != NULL) {

if (p->next->data == data) {

return p;

}

else {

p = p->next;

}

}

return NULL;

}

//删除链表中第一个数据为data的结点

int listDeleteData(Node** phead,Datatype data) { Node* p = NULL; Node* temp = NULL; if (phead == NULL || *phead == NULL) { return -1; }

if ((*phead)->data == data) { temp = (*phead); (*phead) = (*phead)->next; free(temp); return 0; }

p = findPrevNode(*phead, data);

deleteNodeBehind(p);

free(temp);

return 0;

}

//销毁链表

int listDestroy(Node **phead) {

if (phead == NULL || (*phead) == NULL) {

return 0;

}

while ((*phead)->next != NULL) { deleteNodeBehind(*phead); } (*phead) = NULL; free(*phead); //不知道此处有没有错误! return 0; }

int main(int argc, const char * argv[]) {

// 创建结点,查尾,增加结点

Node* p = NULL;

listInsertDataAtTail(&p, 1); //调用了creatNode,findListTail,insertNodeBehind

printList(p);

listInsertDataAtTail(&p, 2);

listInsertDataAtTail(&p, 3);

listInsertDataAtTail(&p, 4);

listInsertDataAtTail(&p, 5);

printf("已有节点:1-2-3-4-5\n");

printList(p);

// 删除

// printf("删除1后面结点\n");

// listDeleteData(&p, 1);

// listDeleteData(&p, 3);

// printList(p);

// 修改

printf("修改2为20000\n");

listChangeData(p, 2, 20000);

printList(p);

listDestroy(&p);

printList(p);

return 0;

}

output:

1

已有节点:1-2-3-4-5

1

2

3

4

5

修改2为20000

1

20000

3

4

5

终于好了~休息了,休息了~晚安,虽然看客还不多,不过慢慢来,会坚持写下去的,最近这样写下来收获还是很大的,毕竟要给别人看(虽然没人哈哈哈哈),有些知识点也补漏了一些~继续加油! 等有人了,多提提意见各位大牛~谢啦

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值