数据结构链表(C语言)

链表

链表的概念及结构

概念:链表是一种物理存储结构上非连续,非顺序的储存结构,数据元素的逻辑顺序是通过链表中的指针连接次序实现的。
在这里插入图片描述
注意:
1.从上图可以看出,链式结构在逻辑上是连续的,但是在物理上不一定连续。
2.现实中的节点一般都是从堆上申请出来的。
3.从堆上申请的空间,是按照一定的策略来分配的,再次申请的空间可能连续,也可能不连续。

#pragma once

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int SLTDAtaType;
typedef struct SListNode
struct SListNode
{
    int datd;
    struct SListNode* next;
}SLTNode;//定义结构体
#include "SList.h"

void TestSList1()//创建一个四个数据的链表
{
      SLTNode* n1=malloc(sizeof(SLTNode));
      assert(n1);
      SLTNode* n2=malloc(sizeof(SLTNode));
      assert(n2);
      SLTNode* n3=malloc(sizeof(SLTNode));
      assert(n3);
      SLTNode* n4=malloc(sizeof(SLTNode));
      assert(n4);
      
      
      n1->data=1;
      n2->data=2;
      n3->data=3;
      n4->data=4;//创建节点
      
      n1->next=n2;
      n2->next=n3;
      n3->next=n4;
      n4->next=NULL;
 }     
int main()
{
 return 0;
}

请添加图片描述
上一个节点存储下一个节点的地址。

打印链表

#include  "SList.h"
void SListPrint(SLTNode* phead)
{
 SListNode* cur=phead;
 while(cur !=NULL)
 {
     printf("%d->",cur->data);
     cur =cur->next;
  }
  printf("NULL\n);
}
cur->next;//结构体访问 (定义结构体)

链表的分类

1.单向或者双向
在这里插入图片描述
2.带头或者不带头
在这里插入图片描述
3.循环或不循环
在这里插入图片描述
1.无头单向非循环链表:结构简单,一般不会单独用来存数据,实际中更多是作为其他数据结构的子结构
2.带头双向循环链表:结构最复杂,一般用在单独存储数据

尾插

头文件void SListPushback(SLTNode* phead,SLTDataType x);
源文件

void SListPushBack(SLTNode** pphead,SLTDataType x)
{
   SLTNode* newnode =(SLTNode*)malloc(sizeof(SLTNode));
   assert(newnode);
   newnode->data =x;
   newnode->next = NULL;
  
   if*pphead==NULL)
   {
     *pphead=newnode;
   }
   else
   {
    //找尾节点
    SListNode*tail = *pphead;
   while(tail->next !=NULL)
   {
      tail = tail->next;
   }   
   tail->next = newnode;
 }      
void TestSList2()//创建一个四个数据的链表
{
     SLTNode* plist=NULL;

      SListPushBack(&plist,5);
      SListPushBack(&plist,6);
      SListPushBack(&plist,7);
      SListPushBack(&plist,8);
      SListPushBack(&plist,9);
      SlistPrint(plist);
 }

头插

void SlistPushFront(SLTNode** pphead,SLTDataType x)
{
  SLTNode* newnode =(SLTNode*)malloc(sizeof(SLTNode));
   assert(newnode);
   newnode->data =x;
   newnode->next = NULL;
   newnode->next=*pphead;
   *pphead=newnode;
}
  void TestSlist2()
  {
    SLTNode* list=NULL;
    SLIstPushFront(&plist,0);
    SListPrint(plist);
  }

头删

void SListPopFront(SLTNode** pphead)
{
    //assert(*pphead!=NULL);
    if(*pphead==NULL)
    return;
    SLTNode* next=(*pphad)->next;
    free(**phead);
    *pphead=next;
}

尾删

void SListPopBack(SLTNode** pphead)
{
   assert(*pphead);
   //只有一个节点 多个节点
   if(*pphead)->next==NULL)
   {
     free(*pphead);
     *pphead=NULL;
   }
   else{
    /* 
   SLTNode* tailPrev=NULL;
   SLTNode* tail=*pphead;
   while(tail->next!=NULL)
   {
     tailPrev=tail;
     tail=tail->next;
   }
   free(tail);
   tailPrev->next=NULL;*/
   SLTNode* tail=*pphead;
   while(tail->next->next!=NULL)
   {
       tail=tail->next;
   }
   free(tail->next);
   tail->next=NULL;
   }
 ]

查找

SLTNode* SListFind(SLTNode* phead,SLTDataType x)
[
    SLTNode* cur=phead;
    while(cur)
    {
      if(cur->data=x)
      return cur;
      cur
}
void TestSList()
{
  SLTNode* plist=NULL;
  SListPushBack(&plist,1);
  SListPushBack(&plist,2);
  SListPushBack(&plist,3);
  SListPushBack(&plist,4);
  SListPushBack(&plist,5);

  SLTNode* ret=SListFind(plist,3);
  if(ret)
  {
    printf("找到了");
    ret->data=30;
    }
    SListPrint(plist);
  }    

在pos位置之前插入

void SListInsert(SLTNode** pphead,SLTNode* pos,SLTDataTyps x)

{
   assert(pos);
   assert(pphead);
   //头插
   if(pos==*pphead)
   {
      SListPushFront(pphead,x);
   }
   else
   {
     SLTNode* prev=*pphead;
     while(prev->next !=pos)
     {
        prev=prev->next;
     }
     SLTNode* newnode=BuySListNode(X);
     //BuySListNode(X);
     
     prev->next=newnode;
     newnode->next=pos;
     }
}                   													

删除pos位置的值

void SListErase(SLTNode** pphead,SLTNode* pos)
{
   assert(pphead);
   assert(pos);
   if(*pphead==pos)
   {
      SListPopFront(pphead);
      }
    else
    {
      SLTnode* prev=*pphead;
      while(prev->next !=pos)
      {
         prev=prev->next;
         }
         prev->next=pos->next;
         free(pos);
       }
}
         

单链表删除pos位置之后插入x

void SListInsertAfter(SLTNode* pos,SLTDataTyps x)
{
  assert(pos);
  /*SLTNode* newnode=BuySListNode(x);
  newnode->next=pos->next;
  pos->next=newnode;*/
  //不在乎链接顺序
  SLTNode*newnoed=BuySListNode(x);
  SLTNide next=pos->nexy;
  //pos newnode next
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
链表是一种数据结构,它由多个节点组成,每个节点包含了数据和指向下一个节点的指针。链表可以动态地增加或删除节点,因此非常适合需要频繁操作的场景。 下面是一个简单的链表C语言实现: ```c #include <stdio.h> #include <stdlib.h> // 链表节点 struct Node { int data; // 数据 struct Node* next; // 指向下一个节点的指针 }; // 创建节点 struct Node* createNode(int data) { struct Node* node = (struct Node*)malloc(sizeof(struct Node)); node->data = data; node->next = NULL; return node; } // 在链表末尾插入节点 void insertAtEnd(struct Node** head, int data) { struct Node* node = createNode(data); if (*head == NULL) { *head = node; } else { struct Node* current = *head; while (current->next != NULL) { current = current->next; } current->next = node; } } // 在链表头部插入节点 void insertAtBeginning(struct Node** head, int data) { struct Node* node = createNode(data); node->next = *head; *head = node; } // 删除链表中的节点 void deleteNode(struct Node** head, int data) { struct Node* current = *head; struct Node* prev = NULL; while (current != NULL && current->data != data) { prev = current; current = current->next; } if (current == NULL) { printf("Node with data %d not found\n", data); return; } if (prev == NULL) { *head = current->next; } else { prev->next = current->next; } free(current); } // 打印链表 void printList(struct Node* head) { struct Node* current = head; while (current != NULL) { printf("%d ", current->data); current = current->next; } printf("\n"); } int main() { struct Node* head = NULL; insertAtEnd(&head, 1); insertAtEnd(&head, 2); insertAtEnd(&head, 3); insertAtBeginning(&head, 0); printList(head); deleteNode(&head, 2); printList(head); return 0; } ``` 这个程序定义了一个`Node`结构体表示链表节点,包含了数据`data`和指向下一个节点的指针`next`。函数`createNode`用来创建节点,函数`insertAtEnd`用来在链表末尾插入节点,函数`insertAtBeginning`用来在链表头部插入节点,函数`deleteNode`用来删除节点,函数`printList`用来打印链表。 在`main`函数中,我们创建了一个空链表`head`,然后依次插入了四个节点。最后打印链表,删除节点2,再次打印链表

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿在线码字

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值