单链表及其操作

一、单链表的基本概念

单链表是线性表链式存储的一种形式,其中的结点一般包含两个域,一个是存放数据信息的info域,另一个是指向该结点的后继结点存放地址的指针next域。

根据单链表首指针指向的内容不同,把单链表分为不带头结点,和带头结点的单链表。

(默认结点从0号下标开始,带头结点链表头结点的next结点为0号)

不带头结点单链表:

 

带头结点单链表:

 

二、单链表的代码实现

1.单链表的基本存储结构

不论是否带头结点,单链表的结点的定义方式都是相同的。将每个结点命名为node,并将指向结点的指针命名为linklist。

typedef int datatype;
typedef struct link_node{
    datatype info;
    struct link_node* next;
}node;
typedef node* linklist;

 

2.创建空表

2.1返回值linklist类型

不带头结点 :

linklist init(){
    return NULL;
}

 

 带头结点:

node* init(){
    linklist head;
    head=(linklist)malloc(sizeof(node));
    head->next=NULL;
    return head;
}

 

2.2无返回值

不带头结点:

void init(linklist *p){
    *p=NULL;
}

 

带头结点:

void init(linklist *p){
    *p=(linklist)malloc(sizeof(node));
    (*p)->next=NULL;
}

 

3.创建单链表

3.1头插法

不带头结点(在键盘上连续输入数据,以空格为间隔,以-999为结束):

linklist creat_linklist_head(){
    datatype x;
    linklist head,s;
    head=NULL;
    printf("Please input the data of linklist(end:-999)\n");
    scanf("%d",&x);
    while(x!=-999){
        s=(linklist)malloc(sizeof(node));
        s->info=x;
        s->next=head;
        head=s;
        scanf("%d",&x);
    } 
    return head;
}

 

带头结点:

linklist creat_linklist_head(){
    datatype x;
    linklist head,s;
    head=(linklist)malloc(sizeof(node));
    head->next=NULL;
    printf("Please input the data of linklist(end:-999)\n");
    scanf("%d",&x);
    while(x!=-999){
        s=(linklist)malloc(sizeof(node));
        s->info=x;
        s->next=head->next;
        head->next=s;
        scanf("%d",&x);
    } 
    return head;
}

 

3.2尾插法

不带头结点:

linklist creat_linklist_rear(){
    datatype x;
    linklist head,r,s;
    head=r=NULL;
    printf("Please input the data of linklist(end:-999)\n");
    scanf("%d",&x);
    while(x!=-999){
        s=(linklist)malloc(sizeof(node));
        s->info=x;
        if(head==NULL)
            head=s;
        else
            r->next=s;
        r=s;
        scanf("%d",&x);    
    } 
    if(r!=NULL) 
        r->next=NULL;    
    return head;
}

 

带头结点:

linklist creat_linklist_rear(){
    datatype x;
    linklist head,r,s;
    head=(linklist)malloc(sizeof(node));
    head->next=NULL;
    r=head;
    printf("Please input the data of linklist(end:-999)\n");
    scanf("%d",&x);
    while(x!=-999){
        s=(linklist)malloc(sizeof(node));
        s->info=x;
        s->next=r->next;
        r->next=s;
        r=s;
        scanf("%d",&x);    
    } 
    return head;
}

 

4.单链表的插入

在position位置上插入值为x的结点。

insert(linklist head,datatype x,int position)

 

4.1返回值linklist类型

不带头结点:

linklist insert(linklist head,datatype x,int position){
    linklist p,q;
    q=get(head,position-1);
    if(!q && position!=0)//如果往空链表第一个位置插入,则q=null,position=0 
        printf("不能在%d号位置上插入\n",position);
    else{
        p=(linklist)malloc(sizeof(node));
        p->info=x;
        if(position==0){//在链表第一个位置(0号)上插入结点 
            p->next=head;
            head=p; 
        }
        else{
            p->next=q->next;
            q->next=p;
        }
    }
    return head;
}

 

带头结点:

linklist insert(linklist head,datatype x,int position)
{
    linklist p,q;
    q=get(head,position-1);
    if(!q && position!=0)//如果往空链表第一个位置插入,则q=null,position=0 
        printf("不能在%d号位置上插入\n",position);
    else{
        p=(linklist)malloc(sizeof(node));
        p->info=x;
        if(position==0){//在链表第一个位置(0号)上插入结点 
            p->next=head->next;
            head->next=p; 
        }
        else{
            p->next=q->next;
            q->next=p;
        }
    }
    return head;
}

 

4.2无返回值

//不想写,懒~ ┗( T﹏T )┛

 

 

5.删除结点

删除单链表中值为x的结点。

不带头结点:

void dele(linklist *head,datatype x){
    linklist p;
    linklist pre=NULL;
    if(!*head){
        printf("单链表为空,无法删除结点!\n");
        return ;
    }
    p=*head;
    while(p && p->info!=x){
        pre=p;
        p=p->next;
    }    
    if(p!=NULL){
        if(!pre)//删除的结点在最前面 
            *head=(*head)->next;
        else
            pre->next=p->next;
        free(p);
    }
} 

 

带头结点:

void dele(linklist *head,datatype x){
    linklist p;
    linklist pre=NULL;
    if(!(*head)->next){
        printf("单链表为空,无法删除结点!\n");
        return ;
    }
    p=(*head)->next;
    while(p && p->info!=x){
        pre=p;
        p=p->next;
    }    
    if(p!=NULL){
        if(!pre)//删除的结点在最前面 
            (*head)->next=p->next;
        else
            pre->next=p->next;
        free(p);
    }
} 

 

6.查找结点

查找第i个位置上的结点,并返回结点(从0下标开始,带头结点head->next结点为0下标)。

不带头结点:

linklist get(linklist head,int position){
    int i=0;
    linklist p=head;
    if(position<0)
        return NULL;
    while(p && position!=i){
        p=p->next;
        i++;
    }
    return p;
}

 

带头结点:

linklist get(linklist head,int position){
    int i=0;
    linklist p=head->next;
    if(position<0)
        return NULL;
    while(p && position!=i){
        p=p->next;
        i++;
    }
    return p;
}

 

7.打印单链表

不带头结点:

void  print(linklist head){
    linklist p;
    p=head;
    if(!p)
        printf("单链表为空,无法打印!\n");
    else{
        while(p){
            printf("%d ",p->info);
            p=p->next;
        }
        printf("\n");
    }
}

 

带头结点:

void  print(linklist head){
    linklist p=head->next;
    if(!p)
        printf("单链表为空,无法打印!\n");
    else{
        while(p){
            printf("%d ",p->info);
            p=p->next;
        }
        printf("\n");
    }
}

 

(○` 3′○) 感谢观看,希望对你有帮助!

posted @ 2022-11-19 16:29  Mr_宋先生  阅读(81)  评论(0编辑  收藏  举报