c语言实现的单链表及一些基本操作

写在前面:
又是一篇学习记录。
单链表算是很经典的一种数据结构了,记得数据结构课本开篇就讲的它。但当时虽然想明白了,却没有用代码实现出来。这次“朝花夕拾”,又碰到这家伙,就决定写下来。(:з)∠)
好了,先附上结构体代码,如下:

typedef struct _NODE
{
 int value;
 struct _NODE* next;
}NODE, *PNODE;

struct _NODE包括一个int 型 value,和一个指向本类型的指针。
为方便使用,又用typedef给这个结构起了俩别名~。

其实我写的单链表的基本操作的基本思想是跟数组类似的,当然也有很多不同,比如插入,删除操作,单链表不用依次移位。
c语言数组基本操作
偷偷写个自己的链接。 []~( ̄▽ ̄)~*
下面是开始进入正题。(严肃脸)
先附上list.h,包含所有函数声明。

list.h ?

#ifndef _LIST_H_
#define _LIST_H_

typedef struct _NODE
{
 int value;
 struct _NODE* next;
}NODE, *PNODE;

void InsertHead(PNODE* ppHead, int value);
void InsertTail(PNODE* ppHead, int value);
void InsertByIndex(PNODE* ppHead, int index, int value);

void DeleteHead(PNODE* ppHead);
void DeleteTail(PNODE* ppHead);
void DeleteByIndex(PNODE* ppHead,int index);
void DeleteByValue(PNODE* ppHead,int value);

PNODE FindByIndex(PNODE pHead, int index);
PNODE FindByValue(PNODE pstart, int value);

void ModifyByIndex(PNODE pHead, int index, int value);
void ModifyByValue(PNODE pHead,int oldvalue, int newvalue);

void Showlist(PNODE pHead);

#endif

一个一个来,( ╯□╰ )

查找 ?

第一个按位置查找:

PNODE FindByIndex(PNODE pHead,int index)
{
 if (index < 0)
 {
  return NULL;  //查找第0个之前的结点则返回NULL
 }
 PNODE pfbi = pHead;
 for (int i = 0; i < index && pfbi != NULL; ++i)
 {
  pfbi = pfbi->next; //从第一个开始依次遍历
 }
 return pfbi;   //找到返回指向该位置的指针,否则返回NULL
}

第二个按值查找:

PNODE FindByValue(PNODE pstart, int value)
{
 PNODE pfbv = pstart;
 while (pfbv != NULL && pfbv->value != value)
 {
  pfbv = pfbv->next; //从第起点开始依次遍历
 }
 return pfbv;   //找到返回指向该位置的指针,否则返回NULL
}

修改 ?

第一个按位置修改:

void ModifyByIndex(PNODE pHead,int index, int value)
{
 PNODE pfind = FindByIndex(pHead, index); //调用按位置查找
 if (pfind != NULL)
 {
  pfind->value = value;     //找到则修改
 }
}

第二个按值修改:

void ModifyByValue(PNODE pHead, int oldvalue, int newvalue)
{
 PNODE pfind = pHead;      //将头指针赋给新建指针
 while (pfind != NULL)
 {
  pfind = FindByValue(pfind, oldvalue); //调用按值查找,每次起点为上次终点
  if (pfind != NULL)
  {
   pfind->value = newvalue;   //找到则修改
  }
 }
}

删除 ?

第一个删除头结点:

void DeleteHead(PNODE* ppHead)
{
 if (*ppHead != NULL)  //不为空链表
 {
  PNODE pdel = *ppHead;
  *ppHead = pdel->next; //头指针指向第一个节点的指向节点
  free(pdel);    //释放节点空间
  //pdel = NULL;   //指针置空
 }
}

第二个删除尾结点:

void DeleteTail(PNODE* ppHead)
{
 if (NULL == *ppHead || NULL == (*ppHead)->next)
 {
  DeleteHead(ppHead);   //如果是空指针,或只有一个节点调用头删函数
 }
 else
 {
  PNODE pdel = *ppHead;
  while (pdel->next->next != NULL)
  {
   pdel = pdel->next;  //下下个节点不为空,则指针后移
  }
  free(pdel->next);   //释放节点空间
  pdel->next = NULL;   //将此时尾节点next值置空
 }
}

第三个按位置删除:

void DeleteByIndex(PNODE* ppHead, int index)
{
 if (index < 0)
 {
  return;      //index小于0则结束函数
 }
 else if (index == 0)
 {
  DeleteHead(ppHead);   //index等于0则调用头删函数
 }
  else
 {
  PNODE ppre = *ppHead;  //前驱指针
  PNODE pdbi = ppre->next;
    for (int i = 1; i < index && pdbi != NULL; ++i)
  {       //从第二个节点开始
   ppre = ppre->next;
   pdbi = pdbi->next;  //两指针后移
  }
  if (pdbi != NULL)
  {       //如果存在该位置结点
   ppre->next = pdbi->next;//上一个结点指向本结点下一个结点
   free(pdbi);    //释放该结点空间
  }
 }
}

第四个按值删除:

void DeleteByValue(PNODE* ppHead, int value)
{
 if (*ppHead != NULL)
 {
  while ((*ppHead)->value == value)
  {
   DeleteHead(ppHead);   //如果第一个结点是要删结点则调用头删函数
  }
    if (*ppHead == NULL)
  {
   return;      //防止所有结点都是要删结点
  }
  PNODE ppre = *ppHead;   //前驱指针
  PNODE pdbv = ppre->next;
    while (pdbv != NULL)
  {
   if (pdbv->value == value)
   {
    ppre->next = pdbv->next;//前驱指针指向本结点的下个结点
    free(pdbv);    //释放本结点空间
    pdbv = ppre->next;  //pdbv指向前驱指针指向结点的下个结点
    continue;
   }
   ppre = ppre->next;
   pdbv = pdbv->next;   //每次循环两指针后移
  }
 }
}

插入 ?

第一个头插:

void InsertHead(PNODE* ppHead, int value)
{
 PNODE pnew = (PNODE)malloc(sizeof(NODE));
  //新建结点并让pnew指向它
 pnew->value = value;
 pnew->next = *ppHead;//新建结点指向头指针指向结点
 *ppHead = pnew;//头指针指向新建结点
}

第二个尾插:

void InsertTail(PNODE* ppHead, int value)
{
 if (NULL == *ppHead)
 {
  InsertHead(ppHead, value);//空链表则调用头插函数
 }
 else
 {
  PNODE pnew = (PNODE)malloc(sizeof(NODE));
  //新建结点并让pnew指向它
  pnew->value = value;
  pnew->next = NULL;//因为尾插所以next置为NULL
  PNODE pTail = *ppHead;
  while (pTail->next != NULL)
  {
   pTail = pTail->next;//找到最后一个结点
  }
  pTail->next = pnew;//让最后一个结点指向新结点
 }
}

第三个按位置插入:

void InsertByIndex(PNODE* ppHead, int index, int value)
{
 if (index <= 0)
 {
  InsertHead(ppHead, value); //默认将index小于等于0的都当头插处理
 }
 else
 {
  PNODE pnew = (PNODE)malloc(sizeof(NODE));
  //新建结点并让pnew指向它
  pnew->value = value;
  PNODE pleft = *ppHead;  //pleft意为指向插入点前一个结点
  PNODE pright = pleft->next; //pright意为指向插入点后一个结点
    for (int i = 1; i < index && pright != NULL; ++i)
  {
   pleft = pleft->next;
   pright = pright->next; //在找到前两指针一直后移
  }
  if (pright != NULL)
  {//如果找到目标位置
   pnew->next = pright;//新结点指向pright指向结点
   pleft->next = pnew;//pleft指向结点指向新结点
  }
  else
  {//如果是插到最后
   pnew->next = NULL;//新结点next置为NULL
   pleft->next = pnew;//pleft指向结点指向新结点
  }
 }
}

输出 ?

还有个输出函数也写上吧,(:з)∠)

void Showlist(PNODE pHead)
{
 PNODE pshow = pHead;//“接收”头指针
 while (pshow != NULL)
 {//挨个儿输出
  printf("%d,", pshow->value);
  pshow = pshow->next;
 }
 puts("\b;");
}

写完啦哈哈哈哈红红火火恍恍惚惚。
自己给自己放个烟花!
男神
谢观~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值