数据结构之链表

数据结构中的链表是可以开辟不连续的空间来存储,那么链表该如何创建和使用呢?

链表的创建

首先创建链表的结构体

struct linklist
{
    int data;//数据域
    struct linklist*link;//指针域
};

然后链表的创建

linklist* creat(int n){//n是线性链表的长度
     int i;
    struct linklist*head=(struct linklist*)malloc(sizeof(struct linklist));//创建头指针
    head->link=NULL;
    if(n==0){
        head=NULL;
        return head;
    }
    struct linklist *p;
    p=head;
    for(i=0;i<n;i++){
        if(i==0) //第一次先将数据放入头指针的数据域中
            scanf("%d",&head->data);
        else{//之后在创建新 的链接点
            struct linklist *s=(struct linklist*)malloc(sizeof(struct linklist));
            scanf("%d",&s->data);
            p->link=s;
            s->link=NULL;//链表末尾的指针域为空
            p=s;
        }
    }
    return head;
} 

链表的一些方法

 

遍历链表,并且输出

void ergidoc(linklist* s){//遍历整个链表
    linklist *p;
    p=s;
    while(p!=NULL){
        printf("%d\t",p->data);
        p=p->link;
    }
    printf("\n");
}

求线性链表的长度

int length(linklist *s){//求线性链表的长度
    linklist *p;
    p=s;
    int n=0;
    while(p!=NULL){
        p=p->link;
        n++;
    }
    return n;
}

判断链表是不是空链表

int isempty(linklist *S){//判断该链表是不是空表
    return S==NULL; //如果是1就是空表,反之则为0
}

返回指定数据的数据域的指针

linklist* find(linklist *s,int w){//找到链表中n的地址
    linklist *p;
    p=s;
    while (p!=NULL && p->data!=w)
    {
        p=p->link;
    }
    return p;
}

插入

在链表的末尾加入

void insertlink1(linklist *s,int w){//在末尾加入一个链接点
    linklist *p;
    linklist *r=(linklist*)malloc(sizeof(linklist));
    r->link=NULL;
    r->data=w;
    p=s;
    while(p->link!=NULL){
        p=p->link;
    }
    p->link=r;
}

在链表的首部加入

linklist* insertlink2(linklist *s,int w){//在链表的头部加入一个链接点
    linklist *p;
    p=s;
    linklist *r=(linklist*)malloc(sizeof(linklist));
    r->link=p;
    r->data=w;
    return r;
}

在指定的数据域后插入

linklist* insertlink3(linklist *s,int w,int y){//在指定的data值后面插入一个链接点
    linklist *p;
    linklist *r=(linklist*)malloc(sizeof(linklist));
    r->data=y;
    p=s;
    while(p!=NULL && p->data!=w){
        p=p->link;
    }
    if (p==NULL){
        printf("error\n");
        return s;
    }
    else{
        linklist *q;
        q=p->link;
        p->link=r;
        r->link=q;
    }
    return s;
}

在指定的位置插入

linklist* insertlink4(linklist *s,int w,int y){//在指定的第i个链接点后面插入一个链接点
    linklist *p;
    linklist *r=(linklist*)malloc(sizeof(linklist));
    r->data=y;
    p=s;
    if (w>length(s)){
        printf("errpr\n");
        return s;
    }
    else{
        for(int i=0;i<w-1;i++){
            p=p->link;
        }
        linklist *q;
        q=p->link;
        p->link=r;
        r->link=q;
    }
    return s;
}

删除

删除指定数据域的所有链接点

void remove1(linklist *s,int w){//删除数据域为w的所有链接点
    linklist *p;
    linklist *q;
    q=s;//q在p的前面
    p=s->link;//先判断第二的链接点的数据域最后再来判断第一个链接点
    while (p!=NULL)
    {
        if(p->data==w){
           q->link=p->link;//使得前面的链接点可以链接到后面
           free(p);
           p=q->link;
        }
        else{
            q=p;
            p=p->link;
        }
    }
    if(s->data==w){//判断第一个链接点
        q=s;
        s=s->link;
        free(q);
    }
}

删除指定的链接点

void remove2(linklist *s,linklist *w){//删除p指向的链接点
    linklist *p;
    linklist* q;
    q=s;
    p=s->link;//先判断第二的链接点的数据域最后再来判断第一个链接点
    while (p!=NULL && p!=w)
    {   q=p;
        p=p->link;
    }
    if (p==NULL)
    {
        printf("error\n");
    }
    else{
        q->link=p->link;
        free(p);
    }
}

删除整个链表

linklist* remove3(linklist *s){//删除整个链表
    linklist *p;
      p=s;
    while (p!=NULL)
    {
        s=p->link;
        free(p);
        p=s;
    }
    return s;
}

总的代码和示例

#include<stdio.h>
#include<stdlib.h>
struct linklist
{
    int data;
    struct linklist*link;
};
linklist* creat(int n){//n是线性链表的长度
     int i;
    struct linklist*head=(struct linklist*)malloc(sizeof(struct linklist));//创建头指针
    head->link=NULL;
    if(n==0){
        head=NULL;
        return head;
    }
    struct linklist *p;
    p=head;
    for(i=0;i<n;i++){
        if(i==0) //第一次先将数据放入头指针的数据域中
            scanf("%d",&head->data);
        else{//之后在创建新 的链接点
            struct linklist *s=(struct linklist*)malloc(sizeof(struct linklist));
            scanf("%d",&s->data);
            p->link=s;
            s->link=NULL;//链表末尾的指针域为空
            p=s;
        }
    }
    return head;
} 
void ergidoc(linklist* s){//遍历整个链表
    linklist *p;
    p=s;
    while(p!=NULL){
        printf("%d\t",p->data);
        p=p->link;
    }
    printf("\n");
}
int length(linklist *s){//求线性链表的长度
    linklist *p;
    p=s;
    int n=0;
    while(p!=NULL){
        p=p->link;
        n++;
    }
    return n;
}
int isempty(linklist *S){//判断该链表是不是空表
    return S==NULL; //如果是1就是空表,反之则为0
}
linklist* find(linklist *s,int w){//找到链表中n的地址
    linklist *p;
    p=s;
    while (p!=NULL && p->data!=w)
    {
        p=p->link;
    }
    return p;
}
void insertlink1(linklist *s,int w){//在末尾加入一个链接点
    linklist *p;
    linklist *r=(linklist*)malloc(sizeof(linklist));
    r->link=NULL;
    r->data=w;
    p=s;
    while(p->link!=NULL){
        p=p->link;
    }
    p->link=r;
}
linklist* insertlink2(linklist *s,int w){//在链表的头部加入一个链接点
    linklist *p;
    p=s;
    linklist *r=(linklist*)malloc(sizeof(linklist));
    r->link=p;
    r->data=w;
    return r;
}
linklist* insertlink3(linklist *s,int w,int y){//在指定的data值后面插入一个链接点
    linklist *p;
    linklist *r=(linklist*)malloc(sizeof(linklist));
    r->data=y;
    p=s;
    while(p!=NULL && p->data!=w){
        p=p->link;
    }
    if (p==NULL){
        printf("error\n");
        return s;
    }
    else{
        linklist *q;
        q=p->link;
        p->link=r;
        r->link=q;
    }
    return s;
}
linklist* insertlink4(linklist *s,int w,int y){//在指定的第i个链接点后面插入一个链接点
    linklist *p;
    linklist *r=(linklist*)malloc(sizeof(linklist));
    r->data=y;
    p=s;
    if (w>length(s)){
        printf("errpr\n");
        return s;
    }
    else{
        for(int i=0;i<w-1;i++){
            p=p->link;
        }
        linklist *q;
        q=p->link;
        p->link=r;
        r->link=q;
    }
    return s;
}
void remove1(linklist *s,int w){//删除数据域为w的所有链接点
    linklist *p;
    linklist *q;
    q=s;//q在p的前面
    p=s->link;//先判断第二的链接点的数据域最后再来判断第一个链接点
    while (p!=NULL)
    {
        if(p->data==w){
           q->link=p->link;//使得前面的链接点可以链接到后面
           free(p);
           p=q->link;
        }
        else{
            q=p;
            p=p->link;
        }
    }
    if(s->data==w){//判断第一个链接点
        q=s;
        s=s->link;
        free(q);
    }
}
void remove2(linklist *s,linklist *w){//删除p指向的链接点
    linklist *p;
    linklist* q;
    q=s;
    p=s->link;//先判断第二的链接点的数据域最后再来判断第一个链接点
    while (p!=NULL && p!=w)
    {   q=p;
        p=p->link;
    }
    if (p==NULL)
    {
        printf("error\n");
    }
    else{
        q->link=p->link;
        free(p);
    }
}
linklist* remove3(linklist *s){//删除整个链表
    linklist *p;
      p=s;
    while (p!=NULL)
    {
        s=p->link;
        free(p);
        p=s;
    }
    return s;
}
int main(){
    linklist* q;
    linklist*w;
    w=creat(5);//创建链表
    insertlink1(w,6);//在末尾加入6
     ergidoc(w);//遍历链表
     w=insertlink2(w,0);//在链表的头部加入0
     ergidoc(w);//遍历链表
     insertlink3(w,4,1001);//指定在4的数据域后加入1001
     ergidoc(w);//遍历链表
     insertlink4(w,8,22222);//在链表的第8个链接点加入22222
     ergidoc(w);//遍历链表
    printf("%d\n",length(w));//输出链表的长度
    printf("%d\n",isempty(w));//判断链表是否为空
    remove1(w,2);//移除 数据域为2 的链接点
    ergidoc(w);//遍历链表
    q=find(w,3);//找到数据域为3 的链接点
    remove2(w,q);//删除指定的链接点
    ergidoc(w);//遍历链表
    w=remove3(w);//删除整个链表
    printf("%d\n",isempty(w));//判断链表是否为空
}

这里我输入了5个数是1,2,3,4,5

结果        

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值