考研数据结构-单链表(基本操作)

Posted J.double

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了考研数据结构-单链表(基本操作)相关的知识,希望对你有一定的参考价值。

这次和以往不同,我们先放出全部代码,之后再慢慢分析。

#include<stdio.h>
#include<malloc.h>
#define ElemType int



typedef struct LNode{
    struct LNode *next;
    ElemType data;
}LNode,*LinkList;


LinkList  CreateLinkListH1(LinkList &L){
//头插法 ,data域来源于键盘输入 
    LNode *s;
    int x;
    L=(LinkList)malloc(sizeof(LNode));
    L->next=NULL;
    scanf("%d",&x);
    while(x!=9999){
        s=(LNode*)malloc(sizeof(LNode));
        s->data=x;
        s->next=L->next;
        L->next=s;
        scanf("%d",&x);
    }
    return L;
}

LinkList  CreateLinkListH2(LinkList &L,int a[],int n){
//头插法 ,data域来源于数组 
    LNode *s;
    L=(LinkList)malloc(sizeof(LNode));
    L->next=NULL;
    for(int i=0;i<n;i++){
        s=(LNode*)malloc(sizeof(LNode));
        s->data=a[i];
        s->next=L->next;
        L->next=s;
    }
    return L;
}




LinkList CreateLinkListR1(LinkList &L){
//尾插法 ,data域来源于键盘输入 
    LNode *s,*r;
    int x;
    L=(LinkList)malloc(sizeof(LNode));
    L->next=NULL;
    r=L;
    scanf("%d",&x);
    while(x!=9999){
        s=(LNode*)malloc(sizeof(LNode));
        s->data=x;
        r->next=s;
        r=s;
        scanf("%d",&x);
    }
    r->next=NULL;
    return L;
} 

LinkList CreateLinkListR2(LinkList &L,int a[],int n){
//尾插法 ,data域来源于数组 
    LNode *s,*r;
    L=(LinkList)malloc(sizeof(LNode));
    L->next=NULL;
    r=L;
    for(int i=0;i<n;i++){
        s=(LNode*)malloc(sizeof(LNode));
        s->data=a[i];
        r->next=s;
        r=s;
    }
    r->next=NULL;
    return L;
} 

void LoadLinkList(LinkList L){
    LNode *p;
    p=L->next;
    if(p==NULL)printf("当前链表为空");
    printf("当前链表元素有:") ;
    while(p!=NULL){
        printf("%d ",p->data);
        p=p->next;
    }
    printf("\n");
}

LNode *GetElem(LinkList L,int i){
//按序号查找第i个结点值 
    int j=1;
    LNode *p;
    p=L->next;
    if(i==0)return L;     //若i==0,则返回头结点 
    if(i<1)return NULL;   //若i无效, 则返回NULL 
    while(j<i&&p){
        p=p->next;
        j++;
    }
    return p;          //返回第i个节点的指针,如果i>表长,p==NULL,也是直接返回p即可。 
}


LNode *LocateElem(LinkList L,int x){
//按值查找表结点 
    LNode *p;
    p=L->next;
    while(p!=NULL&&p->data!=x){
        p=p->next;
    }
    return p;
} 

void LinkListInsertR1(LinkList &L,int i,ElemType e){
//后插操作 ,在给定位置之后插入 
    LNode *p;
    p=GetElem(L,i);         //本算法主要的时间开销在于查找第i-1个元素,时间复杂度为O(n) 
    LNode *s;
    s=(LNode*)malloc(sizeof(LNode));
    s->data=e;
    s->next=p->next;
    p->next=s;
} 
void LinkListInsertR2(LinkList &L,LNode *p,ElemType e){
//在给定结点之后插入,时间复杂度仅为O(1) 
     LNode *s;           
    s=(LNode*)malloc(sizeof(LNode));
    s->data=e;
    s->next=p->next;
    p->next=s; 
} 

void LinkListInsertH1(LinkList &L,int i,ElemType e){
//前插用后插实现 ,在给定位置之前插入 
    LNode *p;
    p=GetElem(L,i-1);         //本算法主要的时间开销在于查找第i-1个元素,时间复杂度为O(n) 
    LNode *s;
    s=(LNode*)malloc(sizeof(LNode));
    s->data=e;
    s->next=p->next;
    p->next=s;
} 

void LinkListInsertH2(LinkList &L,LNode *p,ElemType e){
//前插用后插操作实现,在给定结点之前插入,时间复杂度仅为O(1) 
     LNode *s;     
    ElemType temp;      
    s=(LNode*)malloc(sizeof(LNode));
    s->data=e;
    s->next=p->next;
    p->next=s; 
    temp=s->data;
    s->data=p->data;
    p->data=temp;
} 

void LinkListDelete1(LinkList &L,int i,ElemType &e){
//删除指定位置的结点 
    LNode *p;
    p=GetElem(L,i-1);
    LNode *q=p->next;
    e=q->data;
    p->next=q->next;
    free(q);
} 

void LinkListDelete2(LinkList &L,LNode *p,ElemType &e){
//删除指定结点p 可以通过删除p的后继结点实现,就是先将p的后继节点的值赋给自身,然后删除p的后继节点 
    ElemType temp;
    e=p->data;
    LNode *q;
    q=p->next;
    p->data=q->data;
    p->next=q->next;
    free(q);
} 

int GetLength(LinkList L){
    int len=0;
    LNode *p=L->next;
    if(p==NULL)return 0;
    while(p){
        len++;
        p=p->next;
    }
    return len;
}


int main(){
    LinkList L1,L2;
    int a,i,x; 
    LNode *p,*q; 
//    int array[10]={3,4,6,8,44,2,4,5,6,66}; 
//    printf("头插法建立链表L1\n");  //CreateLinkListH
//    CreateLinkListH1(L1);
//    LoadLinkList(L1);
//    CreateLinkListH2(L1,array,10);
//    LoadLinkList(L1);
//    CreateLinkListR2(L1,array,10);
//    LoadLinkList(L1);
    printf("尾插法建立链表L2\n");   //CreateLinkListR
    CreateLinkListR1(L2);
    LoadLinkList(L2);
    while(1){
        printf("1:计算表长\n");  //GetLength 
        printf("2:指定结点的元素值\n");  //GetElem
        printf("3:按结点位置插入结点\n");
        printf("4:按结点元素插入结点\n");     
        printf("5:按结点位置删除结点\n");
        printf("6:按结点元素删除结点\n"); 
        scanf("%d",&a); 
        switch(a){
            case 1: printf("L1表长为:%d\n",GetLength(L1));
                    printf("L2表长为:%d\n",GetLength(L2));    
                    break;
            case 2: printf("请输入结点位置:");
                    scanf("%d",&i);
                    p=GetElem(L2,i);
                    printf("%d\n",p->data);
                    break;
            case 3: printf("[前插]请输入插入结点位置及元素值");
                    scanf("%d %d",&i,&x);
                    LinkListInsertH1(L2,i,x);
                    LoadLinkList(L2);
                    printf("[后插]请输入插入结点位置及元素值");
                    scanf("%d %d",&i,&x);
                    LinkListInsertR1(L2,i,x);
                    LoadLinkList(L2);
                    break; 
            case 4: printf("[前插]请输入要在哪个元素前插入什么元素值"); 
                    scanf("%d %d",&i,&x);
                    q=LocateElem(L2,i);
                    LinkListInsertH2(L2,q,x);
                    LoadLinkList(L2);
                    printf("[后插]请输入要在哪个元素后插入什么元素值");
                    scanf("%d %d",&i,&x); 
                    q=LocateElem(L2,i);
                    LinkListInsertR2(L2,q,x);
                    LoadLinkList(L2);
                    break;
            case 5: printf("请输入删除结点位置");
                    scanf("%d",&i);
                    LinkListDelete1(L2,i,x);
                    LoadLinkList(L2);
                    break;
            case 6: printf("请输入要删除的元素值");
                    scanf("%d",&i); 
                    q=LocateElem(L2,i);
                    LinkListDelete2(L2,q,x);
                    LoadLinkList(L2);
                    break;
            default:return 1;
        }
    }
}

 

以上是关于考研数据结构-单链表(基本操作)的主要内容,如果未能解决你的问题,请参考以下文章

考研数据结构之单链代码

考研数据结构-单链表(基本操作)

(王道408考研数据结构)第二章线性表-第三节1:单链表的定义及其操作(插入和删除,建立之尾插和头插)

(王道408考研数据结构)第二章线性表-第三节3:循环单链表和循环双链表

(王道408考研数据结构)第二章线性表-第三节2:双链表的定义及其操作(插入和删除)

C语言使用二级指针借助递归工作栈删除单链表中所有值为x的元素