线性表(单链表)基本功能的实现(C语言)(西工大数据结构)


今天我又来发博客啦,刚刚学了链表,现在把一些学的知识总结成博文发出去,希望能对小伙伴们有帮助,也希望各位大佬指出我的错误,码字不易,感谢大家QAQ

链表介绍

链表是一系列的存储数据元素的单元通过指针串接起来形成的,因此每个单元至少有两个域,一个域用于数据元素的存储,另一个或两个域是指向其他单元的指针。这里具有一个数据域和多个指针域的存储单元通常称为节点(node)。
链表的第一个节点和最后一个节点,分别称为链表的头节点和尾节点。尾节点的特征是其 next 引用为空(null)。链表中每个节点的 next 引用都相当于一个指针,指向另一个节点,借助这些 next 引用,我们可以从链表的头节点移动到尾节点。

说这么多,我好久也不懂,所以
上图!
在这里插入图片描述

基本功能

存储结构

typedef int ElemType;

typedef struct Node{//这里的struct node 为结构体类型名,可以用来给变量赋类型
    ElemType data;
    struct Node *next;
}Node,*LinkList;//LinkList 与 Node* 作用一样,这里的Node 和LinkList都可为变量赋类型

头插法

void CreatFromHead(LinkList head)//这里往函数传头指针,用Node *head一样,都是传地址
{                           //头插法
    Node *s;
    char c;
    int flag=1;
    while(flag)
    {
        c=getchar();
        if(c!='$')
        {
            s=(Node*)malloc(sizeof(Node));
            s->data=c;
            s->next=head->next;
            head->next=s;
        }
        else {flag=0;
               }
    }
}

注意 此处要在主函数建立头节点,并把头节点后指向空
头插法是逆序
输入$为止
上图!
在这里插入图片描述
还有,这是开始不把头节点指向空的结果
在这里插入图片描述

尾插法

void CreatFromTail(Node *head)
{
    Node *p;                  //尾插法
    int flag=1;
    p=head;
    char c,d;
    while(flag)
    {
        c=getchar();
        d=getchar();//要将输入时的空格除去
        if(c!='$')
        {
        p->next = (Node*)malloc(sizeof(Node));
        p->next->data=c;
        p = p->next;
        }
        else
        {
            flag=0;
            p->next=NULL;
        }
    }
}

尾插为正序
上图!
在这里插入图片描述

查找

Node *Get(LinkList head,int i)//查找第i个结点,返回结点
{
    int j;
    Node *p;
    if(i<=0) return NULL;
    p=head;
    j=0;
    while(p->next!=NULL&&(j<i))
    {
        p=p->next;
        j++;
    }
    if(i=j) return p;
    else return NULL;
}

返回链表长度

int ListLength(LinkList head)
{
    Node *p;
    p=head->next;
     int j=0;
    while(p!=NULL)
    {
        p=p->next;
        j++;
    }
    return j;

}

输出链表

void OutputList(Node *head){//输出链表
    Node *p = head->next;
    while(p){
        printf("%c ",p->data);
        p = p->next;
    }
}

在第i个结点后插入e

void InsList(LinkList head,int i,char e)//在第i个结点后插入e
{
   Node *pre,*s;
   int k;
   if(i<=0) return;
   pre=head;
   k=0;
   while(pre!=NULL&&k<i)
   {
       pre=pre->next;
       k=k+1;
   }
   if(pre==NULL)
   {
       printf("WRONG PLACE");
       return ;
   }
   s=(Node*)malloc(sizeof(Node));
   s->data=e;
   s->next=pre->next;
   pre->next=s;
   return;

}

删除第i个结点并用e返回其值

void DelList(LinkList head,int i,char *e)//删除第i个结点并用e返回其值
{
    Node *pre,*r;
    int k;
    pre=head;
    k=0;
    while(pre->next!=NULL&&k<i-1)
    {
        pre=pre->next;
        k=k+1;
    }
    if(pre->next==NULL)
    {
        printf("WRONG PLACE");
        return;
    }
    r=pre->next;
    *e=r->data;
    pre->next=r->next;
    free(r);
    return;
}

销毁链表

void DestroyList(LinkList head)//销毁链表
{
    Node *p;
    while(head->next!=NULL)
    {
        p=head->next;
        head->next=p->next;
        free(p);
    }
}

两个链表的有序合并

Node *Merge(Node *head_a, Node *head_b){
    Node *a,*b;
    Node *c,*head_new;
    a=head_a->next;
    b=head_b->next;
    head_new=head_a;
    head_new->next=NULL;
    c=head_new;
    while(a!=NULL&&b!=NULL)
    {
        if(a->data<=b->data)
        {
        c->next=a;
        c=a;
        a=a->next;
        }
        else{
            c->next=b;
            c=b;
            b=b->next;
        }
    }
    if(a)
    {
        c->next=a;
    }
    else c->next=b;
    return(head_new);
}

主体代码

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

typedef int ElemType;

typedef struct Node{//这里的struct node 为结构体类型名,可以用来给变量赋类型
    ElemType data;
    struct Node *next;
}Node,*LinkList;//LinkList 与 Node* 作用一样,这里的Node 和LinkList都可为变量赋类型

void CreatFromHead(LinkList head)//这里往函数传头指针,用Node *head一样,都是传地址
{                           //头插法
    Node *s;
    char c;
    int flag=1;
    while(flag)
    {
        c=getchar();
        if(c!='$')
        {
            s=(Node*)malloc(sizeof(Node));
            s->data=c;
            s->next=head->next;
            head->next=s;
        }
        else {flag=0;
               }
    }
}

void CreatFromTail(Node *head)
{
    Node *p;                  //尾插法
    int flag=1;
    p=head;
    char c,d;
    while(flag)
    {
        c=getchar();
        d=getchar();//要将输入时的空格除去
        if(c!='$')
        {
        p->next = (Node*)malloc(sizeof(Node));
        p->next->data=c;
        p = p->next;
        }
        else
        {
            flag=0;
            p->next=NULL;
        }
    }
}

Node *Get(LinkList head,int i)//查找第i个结点,返回结点
{
    int j;
    Node *p;
    if(i<=0) return NULL;
    p=head;
    j=0;
    while(p->next!=NULL&&(j<i))
    {
        p=p->next;
        j++;
    }
    if(i=j) return p;
    else return NULL;
}

int ListLength(LinkList head)
{
    Node *p;
    p=head->next;
     int j=0;
    while(p!=NULL)
    {
        p=p->next;
        j++;
    }
    return j;

}


void OutputList(Node *head){//输出链表
    Node *p = head->next;
    while(p){
        printf("%c ",p->data);
        p = p->next;
    }
}

void InsList(LinkList head,int i,char e)//在第i个结点后插入e
{
   Node *pre,*s;
   int k;
   if(i<=0) return;
   pre=head;
   k=0;
   while(pre!=NULL&&k<i)
   {
       pre=pre->next;
       k=k+1;
   }
   if(pre==NULL)
   {
       printf("WRONG PLACE");
       return ;
   }
   s=(Node*)malloc(sizeof(Node));
   s->data=e;
   s->next=pre->next;
   pre->next=s;
   return;

}

void DelList(LinkList head,int i,char *e)//删除第i个结点并用e返回其值
{
    Node *pre,*r;
    int k;
    pre=head;
    k=0;
    while(pre->next!=NULL&&k<i-1)
    {
        pre=pre->next;
        k=k+1;
    }
    if(pre->next==NULL)
    {
        printf("WRONG PLACE");
        return;
    }
    r=pre->next;
    *e=r->data;
    pre->next=r->next;
    free(r);
    return;
}
void DestroyList(LinkList head)//销毁链表
{
    Node *p;
    while(p->next!=NULL)
    {
        p=head->next;
        head->next=p->next;
        free(p);
    }
}
int main()
{   char e;
    Node *head;
     head = (Node*)malloc(sizeof(Node));
     head->next=NULL;  //此步是头插法必须的,尾插法不必须
     printf("头插法建表(输入数据为):\n");
    CreatFromTail(head);
    OutputList(head);
     printf("输出前三个数据的地址:\n");
    for(int i=1;i<4;i++)printf("%d ",&*Get(head,i));//注意要取结点的地址
    printf("当前链表长度为%d\n",ListLength(head));
    printf("在第二个元素后插入K后链表为:\n");
    InsList(head,2,'K');
    OutputList(head);
    printf("删除第4个元素后链表为:\n");
    DelList(head,4,&e);
    OutputList(head);
    printf("删除的元素值为%c\n",e);
    printf("销毁链表!");
    DestroyList(head);
    return 0;
}

总结

这篇只是单链表一些简单的操作,本人能力有限,可能有所纰漏,望大家批评指教

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

mcl19909949541

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

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

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

打赏作者

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

抵扣说明:

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

余额充值