数据结构线性表实现单链表各种基本运算





单链表的各种基本运算

文章目录

  • 前言
  • 一,头插法,与尾插法
  • 二,各种基本运算
  • 三,代码展示
  • 总结






前言

链表是一种通用的数据结构,是用一组任意的存储单元存放线性表的元素,这组存储单元可以是连续的也可以不连续,甚至可以零散分布在内存中的任意位置。为了能正确表示元素之间的逻辑关系,每个存储单元在存储数据元素的同时,还必须存储其后继元素所在的地址信息,这个地址信息称为指针,这两部分元素组成了数据元素的存储映像,称为结点(Node)。 本实训项目的主要内容是基于C语言开发一个具有基本功能的单链表。





一、单链表的头插法和尾插法

设给定的数组元素存放在数组a[n]中,建立单链表就是生成存储这n个数据元素的单链表。有两种建立方法:头插法和尾插法。 尾插法的基本思想是每次将新申请的结点插在终端结点的后面,见下图

尾插法的步骤为: 1.初始化一个带头结点的空链表,并领头指针first及尾指针r指向头结点,如上图所示。 2.用循环依次在尾指针所指结点后面插入值为a[i]的新建结点,(i>=0&&i<n) 3.置最后一个结点的指针域为NULL 4.返回指向头结点的指针

代码如下

void CreateLisetF( LinkNdoe *&L,ElemType a[], int n  ){  //采用头插法
    LinkNdoe * s; //用来操作
    L=(LinkNdoe *)malloc( sizeof(LinkNdoe ));//创建头节点
    L->next=NULL;
    for(int i=0;i<n;i++){
        s=(LinkNdoe *)malloc(sizeof(LinkNdoe));//创建新节点
        s->data=a[i];
        s->next=L->next;//将节点S插在原节点之前,头结点之后
        L->next=s;
    }

}

void CreateListR(LinkNdoe *&L,ElemType a[],int n){//采用尾插法
    LinkNdoe *r,*s;
    L=(LinkNdoe*)malloc(sizeof(LinkNdoe));  //创建头结点
    L->next=NULL;
    r=L;
    for(int i=0;i<n;i++){
        s=(LinkNdoe*)malloc(sizeof(LinkNdoe));
        s->data=a[i];
        r->next=s;
        r=s;
    }
    r->next=NULL;//尾结点NEXT为空    

}





二、各种基本运算





1,建立结构

代码如下(示例):

typedef struct LNode
{
    ElemType data;   //
    struct LNode *next;  //指向后继节点
}LinkNdoe;//声明单链表节点类型





2.各种基本运算

(1),初始化单链表

void InitList(LinkNdoe *&L){ //初始化线性表
    L=(LinkNdoe *)malloc(sizeof(LinkNdoe)); //创建头结点
    L->next=NULL;//将单链表置为空表
}

(2),销毁单链表

void DestoryList(LinkNdoe *&L){//销毁单链表
    LinkNdoe *pre=L,*p=pre->next;
    while (p!=NULL)
    {
        free(pre);
        pre=p;
        p=p->next;  //pre p 同步往后移
    }
    

}

(3),判断单链表是否为空表

bool ListEmpty(LinkNdoe *L){  //判断链表是否为空表
    return(L->next==NULL);
}

(4),输出单链表

int ListLength(LinkNdoe *L){    //求单链表的长度
    int i=0;
    LinkNdoe *p=L;
    while (p->next!=NULL)
    {
        i++;
        p=p->next;
    }
    return i;
}

(5),求单链表的第i个元素

void DispList(LinkNdoe *L){ //输出线性表
    LinkNdoe *p=L->next;  //p指向首节点
    while (p!=NULL)
    {
        printf("    %c",p->data);
        p=p->next;
    }
    printf("\n");
}

(6),查找第一个值域为e的值

bool GetElem(LinkNdoe *L,int i,ElemType& e){//求线性表的第i个元素
    int j=0;
    LinkNdoe *p=L;//指向头结点
    if(i<0){
        return false;
    }
    while (j<i&&p!=NULL)
    {
        j++;
        p=p->next;
    }
    if(p==NULL){
        return false;
    }else 
    {   e=p->data;
        return true;
    }
    
}

(7),插入第i个元素

bool ListInsert(LinkNdoe *&L,int i,ElemType e)  //插入第i个元素
{   int j=0;
    LinkNdoe *p=L,*s;
    if(i<=0){
        return false;
    }
    while (j<i-1&&p->next!=NULL)
    {
        j++;
        p=p->next;
    }
    if(p==NULL){
        return false;
    }else{
        s=(LinkNdoe*)malloc(sizeof(LinkNdoe));
        s->data =e;
        s->next=p->next;
        p->next =s;
        return true;
    }
    
    
}

(8),删除第i个值

bool ListDelete(LinkNdoe *&L,int i,ElemType e){//删除第i个值
    int j=0;
    LinkNdoe *p=L,*q;
    if(i<=0){
        return false;
    }
    while (j<i-1&&p->next!=NULL)
    {
        /* code */
        j++;
        p=p->next;
    }
    if(p==NULL){
        return false;
    }else{
        q=p->next;
        if(q==NULL){
            return false;
        }
        e=q->data;
        p->next=q->next;
        free(q);
        return true;
    }
}

所有代码展示

#include <stdio.h>
#include<malloc.h>
typedef char ElemType;

typedef struct LNode
{
    ElemType data;   //
    struct LNode *next;  //指向后继节点
}LinkNdoe;//声明单链表节点类型

void CreateLisetF( LinkNdoe *&L,ElemType a[], int n  ){  //采用头插法
    LinkNdoe * s; //用来操作
    L=(LinkNdoe *)malloc( sizeof(LinkNdoe ));//创建头节点
    L->next=NULL;
    for(int i=0;i<n;i++){
        s=(LinkNdoe *)malloc(sizeof(LinkNdoe));//创建新节点
        s->data=a[i];
        s->next=L->next;//将节点S插在原节点之前,头结点之后
        L->next=s;
    }

}

void CreateListR(LinkNdoe *&L,ElemType a[],int n){//采用尾插法
    LinkNdoe *r,*s;
    L=(LinkNdoe*)malloc(sizeof(LinkNdoe));  //创建头结点
    L->next=NULL;
    r=L;
    for(int i=0;i<n;i++){
        s=(LinkNdoe*)malloc(sizeof(LinkNdoe));
        s->data=a[i];
        r->next=s;
        r=s;
    }
    r->next=NULL;//尾结点NEXT为空    

}
   

void InitList(LinkNdoe *&L){ //初始化线性表
    L=(LinkNdoe *)malloc(sizeof(LinkNdoe)); //创建头结点
    L->next=NULL;//将单链表置为空表
}

void DestoryList(LinkNdoe *&L){//销毁单链表
    LinkNdoe *pre=L,*p=pre->next;
    while (p!=NULL)
    {
        free(pre);
        pre=p;
        p=p->next;  //pre p 同步往后移
    }
    

}

bool ListEmpty(LinkNdoe *L){  //判断链表是否为空表
    return(L->next==NULL);
}

int ListLength(LinkNdoe *L){    //求单链表的长度
    int i=0;
    LinkNdoe *p=L;
    while (p->next!=NULL)
    {
        i++;
        p=p->next;
    }
    return i;
}

void DispList(LinkNdoe *L){ //输出线性表
    LinkNdoe *p=L->next;  //p指向首节点
    while (p!=NULL)
    {
        printf("    %c",p->data);
        p=p->next;
    }
    printf("\n");
}

bool GetElem(LinkNdoe *L,int i,ElemType& e){//求线性表的第i个元素
    int j=0;
    LinkNdoe *p=L;//指向头结点
    if(i<0){
        return false;
    }
    while (j<i&&p!=NULL)
    {
        j++;
        p=p->next;
    }
    if(p==NULL){
        return false;
    }else 
    {   e=p->data;
        return true;
    }
    
}

int LocateElem(LinkNdoe *L,ElemType e){  //查找第一个值域为e的值
    int i=1;
    LinkNdoe *p=L->next;//p指向首节点
    while (p!=NULL&&p->data!=e)
    {
        p=p->next;
        i++;
    }
    if(p==NULL){
        return false;
    }else 
    {
        return i;
    }
    
    
}

bool ListInsert(LinkNdoe *&L,int i,ElemType e)  //插入第i个元素
{   int j=0;
    LinkNdoe *p=L,*s;
    if(i<=0){
        return false;
    }
    while (j<i-1&&p->next!=NULL)
    {
        j++;
        p=p->next;
    }
    if(p==NULL){
        return false;
    }else{
        s=(LinkNdoe*)malloc(sizeof(LinkNdoe));
        s->data =e;
        s->next=p->next;
        p->next =s;
        return true;
    }
    
    
}

bool ListDelete(LinkNdoe *&L,int i,ElemType e){//删除第i个值
    int j=0;
    LinkNdoe *p=L,*q;
    if(i<=0){
        return false;
    }
    while (j<i-1&&p->next!=NULL)
    {
        /* code */
        j++;
        p=p->next;
    }
    if(p==NULL){
        return false;
    }else{
        q=p->next;
        if(q==NULL){
            return false;
        }
        e=q->data;
        p->next=q->next;
        free(q);
        return true;
    }
}


int main(){
    LinkNdoe *h;
    ElemType e;
    printf("单链表的基本运算如下:\n");
    printf("    (1)初始化单链表h\n");
    InitList(h);
    printf("    (2)依次采用尾插法插入a,b,c,d,e元素\n");
    ListInsert(h,1,'a');
    ListInsert(h,2,'b');
    ListInsert(h,3,'c');
    ListInsert(h,4,'d');
    ListInsert(h,5,'e');
    printf("    (3)输出单链h:");
    DispList(h);
    printf("    (4)单链表h的长度:%d\n",ListLength(h));
    printf( "   (5)单链表h为%s\n",(ListEmpty(h))?"空":"非空");
    GetElem(h,3,e);
    printf("    (6)单链表h中第3个元素:%c\n",e);
    printf("    (7)元素a的位置:%d\n",LocateElem(h,'a'));
    printf("    (8)在第4个位置插入f元素\n");
    ListInsert(h,4,'f');
    printf("    (10)删除h上的第3个元素\n");
    ListDelete(h,3,e);
    printf("    (11)输出单链表h:\n");
    DispList(h);
    printf("    (12)释放单链表h\n");
    DestoryList(h);
    return 0;


}





总结

单链表是学习数据结构中,必须学习的重要知识。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值