手机阅读

2023年c语言链表的基本操作 c语言链表知识点总结汇总

格式:DOC 上传日期:2023-05-02 22:20:24 页码:12
2023年c语言链表的基本操作 c语言链表知识点总结汇总
2023-05-02 22:20:24    小编:zdfb

总结是对某一特定时间段内的学习和工作生活等表现情况加以回顾和分析的一种书面材料,它能够使头脑更加清醒,目标更加明确,让我们一起来学习写总结吧。优秀的总结都具备一些什么特点呢?又该怎么写呢?下面是我给大家整理的总结范文,欢迎大家阅读分享借鉴,希望对大家能够有所帮助。

c语言链表的基本操作 c语言链表知识点总结篇一

链表是数据结构中比较基础也是比较重要的类型之一,那么有了数组,为什么我们还需要链表呢!或者说设计链表这种数据结构的初衷在哪里?下面小编就为大家介绍下c语言链表的用法。

链表的定义一般使用结构体,在看《数据结构与算法分析》这本书的时候发现,书中频繁的使用typedef的关键字,结果真的很棒不仅保持的代码的整洁程度,也让我们在下面的编码过程中少见了很多烦人的指针(当然指针还是一直存在的)。所以这里也借用了书中的定义方法。

struct node;

typedef struct node* ptrnode;

typedef ptrnode position;

typedef ptrnode list;

struct node{

int value;

ptrnode next;

};

下面接着书写一个建立链表的函数,输入每个节点的值,直到这个值是-1的时候函数结束。

在这个里面,我以前一直搞不明白为什么需要定义三个node *,现在终于了解了,最终还是复习了指针的内容明白的.,这里说一下指针实现链表对指针的操作很频繁,需要比较扎实的掌握了指针之后,在来看链表会轻松很多。在下面的一段程序里,我分别定义了head/p/tmp这三个指向节点结构体的指针,head的主要作用就像一个传销头目,他会主动联系上一个下线p,然后他就什么也不干了,p接着去发展一个又一个的下线tmp,结果一串以head为首的链表就出来了。

起先,我总觉得有了head,为什么还要p,这是因为如果直接使用head去指向下一个节点,head的位置也是不断在移动的,即它永远处于链表的尾端,这样当我们返回链表的时候,其实是空值。所以,我们需要p这个中转环节。(其实,这种做法在指针中非常普遍,大部分有返回指针类型的函数中,都会首先定义一个指针变量来保存函数的传入的参数,而不是对参数直接进行操作)。

/*

函数功能:创建一个链表

函数描述:每次输入一个新的整数,即把新增加一个节点存放该整数,

当输入的整数为-1时,函数结束。

*/

list create()

{

int n=0;

position p,head,tmp;

head=null;

tmp=malloc(sizeof(struct node));

if(tmp==null)

{

printf("tmp malloc failed! ");

return null;

}

else

{

p=tmp;

printf("please input the first node's message! ");

scanf("%d",&(tmp->value));

}

while(tmp->value!=-1)

{

n+=1;

if(n==1)

{

head=p;

tmp->next=null;

}

else

{

p->next=tmp;

}

p=tmp;

tmp=malloc(sizeof(struct node));

printf("please input the %d node! ",n+1);

scanf("%d",&(tmp->value));

}

p->next=null;

free(tmp); //free函数free掉的只是申请的空间,但是指针还是依然存在的。

tmp=null;

return head;

}

接下来,在写一个删除链表节点的函数,输入一个整数然后遍历链表节点,当链表节点的值与该整数相等的时候,即把该节点删除。

在完成这个函数首先一定要把这个过程思考清楚,不可否认我之前是一个上来就敲代码的人,看了《剑指offer》感觉这种习惯是程序员的大忌,甚至还想写一篇博客,名字都想好了《程序员的自我修养之思考在前,代码在后》。其实想想也是,我们写程序的目的是为了解决问题,而不是为了简单的写程序,纯粹的让程序跑起来大概只会在上学那会存在吧!真实的程序开发中需要考虑几乎所有 能想到的实际问题,所以无论程序再下,一要学会先思考清楚,再下笔写程序。

关于这个函数,我们要想到的是:

1 如果链表为空,我们该怎么做,当然是直接返回。

2 如果要删除的元素为头节点该怎么办?

3 如果要删除的元素为尾节点该怎么办?

当注意到以上三个部分,我们的程序就可能避免掉了输入链表为空,程序直接崩溃的现象,也可以避免删除元素值为头节点时删不掉的尴尬。我们的程序就有了一定的鲁棒性。

下面着重考虑链表的删除的实现:

list: ???? node_a->node_b->node_c->node_d;

?????????????? list ?????? tmp???????? p

-------> ?????? ? ? ? tmp->next=p->next;

list:?????? node_a->node_b----------->node_d

????????????????????????????????????? free(p)

假设我们要删除的节点为上图的node_c;假设我们能够找到node_c的前一个位置tmp和被删除节点位置p的话;这个时候我们只需要执行tmp->next=p->next即可。

只要完成上面的分析以及考虑到各种情况,我们完成下面的代码就水到渠成了。

/*

函数功能:删除链表中指定值的节点(如果存在多个,只删除第一个)

本例中输入一个整数,删除链表节点值为这个整数的节点。

*/

list deletenode(list list)

{

position p,tmp;

int value;

if(list==null)

{

printf("the list is null,function return! ");

return null;

}

else

{

printf("please input the node's value: ");

scanf("%d",&value);

}

p=list;

if(p->value==value)

{

list=p->next;

free(p);

p=null;

return list;

}

while(p!=null&&p->value!=value)

{

tmp=p;

p=p->next;

}

if(p->value==value)

{

if(p->next!=null){

tmp->next=p->next;

}

else

{

tmp->next=null;

}

free(p);

p=null;

}

return list;

}

关于链表的使用场景分析:

链表在程序开发中用到的频率还是非常高的,所以在高级语言中往往会对链表进行一些实现,比如stl中list以及java中也有类似的东西。在目前的服务器端开发,主要运用链表来接收一些从数据中取出来的数据进行处理。

即使你不知道链表的底层实现,仍然可以成功的运用stl里面的现成的东西。但是作为一个学习者,我觉得会使用和从底层掌握仍然是两个不同的概念,linux之父说:“talk is less,show you code”。

以下的程序,用链表模拟了一个电话通讯录的功能,包括添加联系人,查找联系人,以及删除联系人。

ps:关于鲁棒性,程序中最大的危险是使用了gets这个函数,目前先保留使用gets,等待找到工作之后在做进一步的程序完善。(尼玛,读书去。。。应届生,找个工作他妈咋这么难呢!?? 工作经验,工作经验,艹,那个大牛一出校门就什么都会。)

/**************************************************************************

programe:

this is a phone list write by list

the programe is just prictise for list

author: heat nan

mail:964465194@

data:2015/07/27

**************************************************************************/

#include

#include

#include

#define n 25

#define m 15

struct node;

typedef struct node* p_node;

typedef p_node list;

typedef p_node position;

typedef struct node** plist;

struct node{

char name[n];

char number[m];

position next;

};

int judgenameexist(list list,char* name);

void addperson(plist list);

void printlist(list list);

list findperson(list list);

list findpersonbyname(list list,char* name);

int addpersonbyname(plist list,list node);

int deletepersonbyname(plist list,char* name);

void deleteperson(plist list);

int main()

{

list list=null;

position p;

char cmd[100];

while(1)

{

printf(" main ");

printf(" ******* 1 add a person ******* ");

printf(" ******* 2 show the phone list ******* ");

printf(" ******* 3 find from phone list ******* ");

printf(" ******* 4 from phone list ******* ");

printf("please input the cmd number: ");

gets(cmd);

switch(cmd[0])

{

case '1':

addperson(&list);

break;

case '2':

printlist(list);

break;

case '3':

findperson(list);

break;

case '4':

deleteperson(&list);

break;

default:

printf("wrong cmd! ");

break;

}

}

return 0;

}

/*

function:判断要添加的联系人名称是否已经存在于电话簿中.

input: list 电话列表,name 要添加的联系人的姓名.

return: 已经存在返回1,不存在返回0.

*/

int judgenameexist(list list,char* name)

{

if(findpersonbyname(list,name)!=null)

return 1;

else

return 0;

}

/*

function:根据输入的姓名查找联系人的信息节点

input: 要输入的电话列表list,姓名name

return: 返回查找到的节点

*/

list findpersonbyname(list list,char* name)

{

while(list!=null)

{

if(strcmp(list->name,name)==0)

break;

list=list->next;

}

return list;

}

/*

function:根据姓名添加新的联系人到联系人列表

input: 指向联系人列表地址的指针, 新用户节点

return: 添加成功返回1,添加失败返回0

*/

int addpersonbyname(plist list,list node)

{

if(node==null)

{

printf("the node is null! ");

return 0;

}

if(*list==null)

{

*list=node;

return 1;

}

list phead=*list;

while(phead->next!=null)

phead=phead->next;

phead->next=node;

return 1;

}

void addperson(plist list)

{

position tmp;

position p_head;

tmp=(struct node*)malloc(sizeof(struct node));

char name[n];

char number[m];

if(tmp==null)

{

printf("malloc the tmp node failed in function add person! ");

}

else

{

printf("please input the name: ");

gets(name);

printf("please input the number: ");

gets(number);

strcpy(tmp->name,name);

strcpy(tmp->number,number);

tmp->next=null;

}

if(judgenameexist(*list,name)==1)

{

free(tmp);

printf("the name have already exist! ");

return;

}

addpersonbyname(list,tmp);

}

/*

function: 打印联系人列表

input: 联系人列表

*/

void printlist(list list)

{

position show;

show=list;

if(show==null)

{

return ;

}

printf("now,we print the phone list: ");

while(show!=null)

{

printf("name:%s number:%s ",show->name,show->number);

show=show->next;

}

}

list findperson(list list)

{

char name[n];

position phead=list;

printf("please input the name you will find: ");

gets(name);

position node=findpersonbyname(list,name);

if(node!=null)

printf("find success! name-> %s number-> %s ",node->name,node->number);

else

printf("find failed! ");

return node;

}

/*

function:根据姓名删除联系人

input: 指向联系人地址的指针,联系人姓名

output: 删除成功返回1,失败返回0

*/

int deletepersonbyname(plist list,char* name)

{

if(*list==null||name==null)

return 0;

list phead=*list;

if(strcmp(phead->name,name)==0)

{

*list=phead->next;

free(phead);

phead->next==null;

return 0;

}

list tmp=phead->next;

while(tmp!=null)

{

if(strcmp(tmp->name,name)==0)

{

phead->next=tmp->next;

free(tmp);

tmp->next=null;

return 1;

}

phead=tmp;

tmp=tmp->next;

}

return 0;

}

void deleteperson(plist list)

{

list phead=*list;

if(phead==null)

{

printf("there is no person you can delet ");

return ;

}

char name[n];

printf("please input the name: ");

gets(name);

deletepersonbyname(list,name);

}

s("content_relate");

【c语言链表的用法有哪些】相关文章:

1.c语言链表的用法2.c语言assert的用法有哪些3.c语言if语句的用法有哪些4.c语言中int的用法有哪些5.c语言中indexof的用法有哪些6.c语言小括号的用法有哪些7.c语言的循环链表和约瑟夫环8.c语言的应用有哪些

您可能关注的文档

相关文档