链表的组成、创建、遍历及增删改查

一、 链表的组成:

头指针(Header)和若干个节点(节点包括了数据域和指针域),最后一个节点要指向空。

链表的实现原理:头指针指向链表的第一个节点,然后第一个节点中的指针指向下一个节点,然后依次指到最后一个节点,这样就构成了一条链表。

1.定义一个结点

struct Node{
    int data;                    //存放数据
    struct Node* next;           //指针,用来访问结点数据,也可以遍历指向下一个结点
};

2.创造链表的头结点:

struct Node* creatNode(){
      struct Node *ptmp;
  
      ptmp = (struct Node*)malloc(sizeof(struct Node));     //为结点申请分配内存
                                                            //malloc在栈上分配内存
      if(ptmp == NULL){
          printf("malloc failed\n");                        //内存分配失败
      }
 
      memset(ptmp, '\0', sizeof(struct Node));              //清零  
                                                            //将结点初始化
      ptmp->data = 0;
      ptmp->next = NULL;
  
      return ptmp;
 }

3.链表增加结点:

void addNode(struct Node* head, int data){               //data为新加结点的值
  struct Node *pnode;
  pnode = head;
  if(pnode == NULL){                                     //头结点是否为空
      printf("This linklist is NULL");
      return;
  }


  struct Node *newNode;
  newNode = (struct Node*)malloc(sizeof(struct Node));

  if(newNode == NULL){
      printf("malloc failed\n");                        //为新结点分配内存
  }

  newNode->data = data;
  newNode->next = NULL;

  while(pnode->next != NULL){                           //找到链表的尾
    pnode = pnode->next;
  }

  pnode->next = newNode;                                //将新创的结点加入链表

  return;
}

4.遍历链表

void printLinklist(struct Node* phead){
  struct Node *ptmp;
  ptmp = phead;

  if(ptmp == NULL){
      printf("This linklist is NULL");
      return;
  }

  while(ptmp != NULL){
    printf("%d\t", ptmp->data);
    ptmp = ptmp->next;
  }
  puts("");                                       //遍历结束后换行
  return;
}

5.删除某个位置的结点L1

        5.1 先得到想要删除节点的前一个结点记为L2,即查找某个位置的值

struct Node* getPosTolinklist(struct Node* phead, int pos){
  struct Node *ptmp;
  ptmp = phead;

  if(ptmp == NULL){
      printf("This linklist is NULL");
      return NULL;
  }

  while(pos--){                                             //注:从0开始计数的位置
      ptmp = ptmp->next;
  }

  return ptmp;
}

        5.2将L2结点的next等于L1的next即完成结点的删除

        

void deleteNodeTolinklist(struct Node* phead, int pos){

  struct Node *ptmp;
  struct Node *deleteNode;
  ptmp = phead;

  if(ptmp == NULL){
      printf("This linklist is NULL");
      return;
  }
  ptmp = getNodePosTolinklist(phead, pos-1);            //得到想要删除结点的前一个结点
  deleteNode = ptmp->next;
  ptmp->next = deleteNode->next;

  free(deleteNode);                                     //释放结点

  return;
}

6.更改某个位置结点的值

        利用5.1得到更改位置的结点,对该结点的data重新赋值即可。

        

void changNodedataToLinklist(struct Node* phead, int pos, int data){
  struct Node *ptmp;
  struct Node *changeNode;
  ptmp = phead;

  if(ptmp == NULL){
      printf("This linklist is NULL");
      return;
  }

  changeNode = getNodePosTolinklist(phead, pos);              //得到想要更改位置的结点
  changeNode->data = data;                                    // 更改data值

  return;
}

下面是我写的一个完整demo:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


int main()
{
  int data;
  int pos;                                 // 可以让用户自定义pos的值
  struct Node *phead;

  phead = creatNode();
  int i;
  i = 5;
  while(i--){                             //为链表添加5个结点
    printf("请输入要插入链表的值");
    scanf("%d", &data);
    addNode(phead, data);
  }

  printLinklist(phead);

  deleteNodeTolinklist(phead, 4);            // 可以用scanf输入pos的值,这里直接设置为4

  printLinklist(phead);

  changNodedataToLinklist(phead, 0, 100);    //可以用scanf输入pos的值,这里直接设置为0
                                             //                    data直接设置为100

  printLinklist(phead);

  return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值