【小白】线性表的链式存储结构的实现(C语言版)

文章目录

  • 前言
  • 一、线性表的链式存储结构的实现
    • 1.实现所需要的主函数
    • 2.常量定义
    • 3.定义结构体
    • 4.实现
      • 4.1单链表的初始化
      • 4.2单链表的建立-头插法
      • 4.3单链表的建立-尾插法(带头结点)
      • 4.4单链表的清空
      • 4.5获取单链表的长度
      • 4.6判断单链表是否为空
      • 4.7获取单链表中的内容
      • 4.8单链表的插入(在第i个位置之前插入)
      • 4.9单链表的删除(删除第i个位置的节点)
      • 4.10获取某个位置的元素
  • 二.总结


前言

提示:最近小菜加入研究所了有点忙,就一直没有发博客,朋友催着我发,今晚会多发几章,欢迎同学们和我一块讨论数据结构,小菜对一些也不是很会,带带我!!!


一、线性表的链式存储结构的实现

1.实现所需要的主函数

代码如下(示例):

int InitList(LinkList *L);
void CreateList_Head(LinkList *L, int n);
void CreatList_Tail(LinkList *L, int n);
int List_Clean(LinkList *L);
int List_length(LinkList L);
int List_Empty(LinkList L);
int Link_Get(LinkList L);
int Link_Insert(LinkList *L, int i, int data);
int Link_Delete(LinkList *L, int i);
int GetElem(LinkList L,int i, int *e);

2.常量定义

#define OK 0;
#define ERROR 1;
#define TRUE 1;
#define FALSE 0;

3.定义结构体

typedef struct LNode{
     
    int data;
    struct LNode *next;
}LNode;
typedef struct LNode *LinkList;

4.实现

4.1单链表的初始化

int InitList(LinkList *L){
     
	//为L动态分配内存
    *L = (LinkList ) malloc(sizeof(LNode));
    //分配内存不成功
    if(!(*L))
        return ERROR;
    (*L)->next = NULL;
    return OK;
}

4.2单链表的建立-头插法

void CreateList_Head(LinkList *L, int n){
     
	//该文中单链表为带头结点的单链表	
	//设置头结点
   *L = (LinkList) malloc(sizeof(LNode));
   //为插入结点时,头结点的next值为NULL
   (*L)->next = NULL;
   //建立n个结点
   for(int i = n; i > 0; i--){
     
       LNode *p = (LNode *)malloc(sizeof(LNode));
       scanf("%d",&p->data);
       p->next = (*L)->next;
       (*L)->next = p;
   }
}

4.3单链表的建立-尾插法(带头结点)

void CreatList_Tail(LinkList *L, int n){
     
    *L = (LinkList) malloc(sizeof(LNode));
    (*L)->next = NULL;
    //保证单链表的地址不会发生改变,重新设置一个指针参与链表的建立
    LNode *r = *L;
    for(int i = 0 ;i < n; i++){
     
        LNode *p = (LNode *) malloc(sizeof(LNode));
        scanf("%d",&p->data);
        r->next = p;
        p->next = NULL;
        //将最后一个节点的地址赋值给r
        r = p;
    }
}

4.4单链表的清空

int List_Clean(LinkList *L){
     
    LinkList p;
    //保留头结点
    p = (*L)->next;
    while(p){
     
        LinkList q;
        q = p;
        free(q);
        p =p->next;
    }
    (*L)->next = NULL;
    printf("已清空!");
    return OK;
}

4.5获取单链表的长度

int List_length(LinkList L){
      
	//该函数不需要对链表做出任何修改,所以形参不需要*L(指向链表的指针的指针)
	//用count计数
    int count = 0;
    //L指向首元结点
    L = L->next;
    while(L){
     
        count++;
        L = L->next;
    }
    return count;
}

4.6判断单链表是否为空

int List_Empty(LinkList L){
     
	//判断头结点的next域是否为空
    if(L->next)
        return FALSE;
    return TRUE;
}

4.7获取单链表中的内容

int Link_Get(LinkList L){
     
    printf("获取单链表中的数据元素\n");
    //L指向首元结点
    L = L->next;
    //判断next域是否为空
    while(L){
     
        printf("%d\t",L->data);
        L = L->next;
    }
    return OK;
}

4.8单链表的插入(在第i个位置之前插入)

int Link_Insert(LinkList *L, int i, int data){
     
	//i为插入位置
	//data为要插入的数据
    int j = 0;
    LinkList P = *L; 
    //查找第(i-1)个节点
    //p:判断单链表是否为空/i大于链表长度
    //j < i-1: 插入位置小于1
    while(P &&j < i-1){
     
        P = P->next;
        j++;
    }
    //插入位置不正确
    if(!P || j > i-1)
        return ERROR;
     //建立新的节点
    LNode *Lnode = (LNode *) malloc(sizeof(LNode));
    (*Lnode).data = data;
    (*Lnode).next = P->next;
    P->next = Lnode;
    return OK;
}

4.9单链表的删除(删除第i个位置的节点)

int Link_Delete(LinkList *L, int i){
     
    int j = 0;
    LinkList P = *L;
    //寻找第(i-1)个节点
    while(P && j < i-1){
     
        P = P->next;
        j++;
    }
    //如果超出链表长度或者要删除的位置小于1
    if(!P || j > i-1)
        return ERROR;
    LinkList q;
    q = P->next;
    P->next = P->next->next;
    //释放该节点
    free(q);
    return OK;
}

4.10获取某个位置的元素

int GetElem(LinkList L,int i, int *e ){
     
    LNode *p = L->next;
    int j = 1;
    //当p指向NULL或者j>=i时不执行循环
    while(p && j < i){
     
        p = p->next;
        j++;
    }
    //判断是否超出链表长度或者要获取元素的位置是否小于1 
    if(j > i || !p)
        return ERROR;
    *e = p->data;
    return OK;
}

二.总结

链表的链式存储结构的优点:插入、删除运算方便。不需要一块连续的内存空间。
链表的链式存储结构的缺点:链表是顺序存储,要查找某一元素的时间复杂度为O(n)。

你可能感兴趣的:(c语言,数据结构,链表)