上海龙凤419

C说话

c说话链表的用法

时辰:2024-10-20 20:02:44 C说话 我要投稿
  • 相干保举

c说话链表的用法

  链表是数据布局中比拟根本也是比拟首要的范例之一,那末有了数组,为甚么咱们还须要链表呢!或说设想链表这类数据布局的初志在那里?上面小编就为大师先容下c说话链表的用法。

  c说话列举的用法以下:

  这是由于,在咱们利用数组的时辰,须要事后设定方针群体的个数,也即数组容量的巨细,可是及时环境下咱们方针的个数咱们是不肯定的,是以咱们老是要把数组的容量设置的很大,如许以来就华侈了良多的空间。别的,数组在停止拔出操纵和删除操纵的时辰,在拔出或删除拟定元素以后,咱们常常须要停止轮回移位,这增添了咱们的线性开消。

  恰是由于以上的两种首要缘由,链表被设想出来用于普通表的操纵。为了防止上面描写数组的两种弊病,咱们但愿链表有一下的特色

  1 能够或许矫捷的扩大本身的长度。

  2 存储地点不持续,删除或拔出操纵的时辰不须要轮回移位。

  要完成以上两个特色,咱们需既要保障每一个节点的自力性,又要保管相邻两个节点的接洽。

  为此,链表普通被设想为上面的情势。

  Node--->Node---->Node

  链表是由一个一个的节点构成的,能够或许便利和自在的拔出未知个Node,前一个节点顶用指针保管着下一个节点的地位,如许以来便顺遂的完成了咱们对链表的两点希冀,可是独一的毛病谬误是增添了额定的空间耗损。

  ————————————————————————————————————————————————————————————————————————————

  链表的界说:

  链表的界说普通利用布局体,在看《数据布局与算法阐发》这本书的时辰发明,书中频仍的利用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:[email protected]

  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);

  }

【c说话链表的用法】相干文章:

C说话链表逆序方式技能08-21

链表的C说话完成方式08-27

C说话的轮回链表和约瑟夫环09-29

C说话assert用法06-24

C说话#include用法10-17

C说话#define的用法08-19

c说话if语句的用法07-23

assert用法(C说话)05-30

C说话assert的用法10-29

链表的C说话完成方式编程进修06-12