单链表及其操作(C实现)

2021-04-27  本文已影响0人  大成小栈

当每一个数据结点都和下一个数据结点用指针链接在一起时,就形成了一个链,这个链子的头就位于第一个数据元素,这样的存储方式就是链式存储。

1. 链表的构成

每个结点的结构,以及单链表的构成,如下:

typedef struct Link
{
  char elem; // 数据域
  struct Link * next;  // 指针域
} link;

2. 头结点、头指针和首元结点

若头结点的指针域为空(NULL),表明链表是空表。头结点对于链表来说,不是必须的,在处理某些问题时,给链表添加头结点会使问题变得简单。
单链表中可以没有头结点,但是不能没有头指针!

3. 单链表的创建

例如,创建一个链表(1,2,3,4):

link * initLink()
{
  link * p = (link*)malloc(sizeof(link));  // 创建头结点
  link * temp = p;  // 声明一个指针指向头结点,用于遍历链表
  
  //生成链表
  for (int i=1; i<5; i++) 
  {
    link *a = (link*)malloc(sizeof(link));
    a->elem = i;
    a->next = NULL;
    temp->next = a;
    temp = temp->next;
  }
  return p;
}

4. 单链表的遍历

查找某结点:

int selectElem(link * p, int elem)
{
  link *t = p;
  int i = 1;
  while (t->next) 
  {
    t = t->next;
    if (t->elem == elem) 
    {
      return i;
    }
    i++;
  }
  return -1;
}

修改某结点数据域:

link *amendElem(link * p, int add, int newElem)
{
  link * temp = p;
  temp = temp->next;  //在遍历之前,temp指向首元结点
  //遍历到被删除结点
  for (int i=1; i<add; i++) 
  {
    temp = temp->next;
  }
  temp->elem = newElem;
  return p;
}</pre>

向链表中插入结点:

// 创建临时指针,断链续接
link * insertElem(link * p, int elem, int add)
{
  link * temp = p;  //创建临时结点temp
  //首先找到要插入位置的上一个结点
  for (int i=1; i<add; i++) 
  {
    if (temp == NULL)
     {
      printf("插入位置无效\n");
      return p;
    }
    temp = temp->next;
  }
  //创建插入结点c
  link *c = (link*)malloc(sizeof(link));
  c->elem = elem;
  //向链表中插入结点
  c->next = temp->next;
  temp->next = c;
  return p;
}</pre>

从链表中删除节点:

// 把结点摘下来,续接,再释放掉
link * delElem(link * p,int add)
{
  link * temp = p;
  //temp指向被删除结点的上一个结点
  for (int i=1; i<add; i++) 
  {
    temp = temp->next;
  }
  link * del = temp->next;//单独设置一个指针指向被删除结点,以防丢失
  temp->next = temp->next->next;//删除某个结点的方法就是更改前一个结点的指针域
  free(del);//手动释放该结点,防止内存泄漏
  return p;
}
上一篇 下一篇

猜你喜欢

热点阅读