数据结构--线性表的链式存储(3)

一、什么是链表

  线性表的链式存储又称之为单链表,他是通过内存中任意一块区域来存储数据元素的,为了让每一块的元素建立逻辑关系,我们把每一块的数据存储单元分为两个部分,第一个部分为数据部分,第二个部分为指向下一个节点的指针,所以在插入和删除的时候,链表不需要对元素大量的进行移动,只需修改指针即可。

数据结构--线性表的链式存储(3)

 

二、链表的特点

  1.解决了顺序表在存储数据时需要大量连续的空间,属于非随机存储。

  2.由于存在指针域,链表消耗的空间会比较大。

  3.链表进行删除和插入时候时间复杂度为O(1),因为只需修改指针的指向而已。

  4.查找时消耗比较大,需要从头开始遍历,时间复杂度为O(n)。

  本人觉得顺序表和链表是一个互补的出现,往往某些场合需要两者结合才能完成。

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

  头插法时元素始终插入头节点后面,比如说插入的元素为1,2,3,4,5,所以在输出的时候为5,4,3,2,1

数据结构--线性表的链式存储(3)

 

头插法代码如下

LinkList InsertHead(LinkList L) {        //头插法
    LinkNode *s;
    int n;
    scanf("%d", &n);
    while (n != -1) {        //输入为-1时表示终止输入
        s = (LinkNode*)malloc(sizeof(LinkNode));
        s->data = n;
        s->next = L->next;
        L->next = s;
        scanf("%d", &n);
    }
    return L;
}

  尾插法在插入元素时候每次都在节点最后插入,所以元素的顺序不会变。

数据结构--线性表的链式存储(3)

 

 尾插法代码如下

LinkList InsertTail(LinkList L) {        //尾插法
    int n;
    LinkNode *s;
    LinkNode *end = L;        //尾指针
    scanf("%d", &n);

    while (n != -1) {        //输入-1时退出
        s = (LinkNode*)malloc(sizeof(LinkNode));
        s->data = n;
        end->next = s;
        end = s;        //end指向新的尾节点
        scanf("%d", &n);
    }
    end->next = NULL;        //尾节点指针置为空
    return L;
}

 

 四、单链表的增、删、改、查操作

  linkList.h头文件

#include<stdio.h>

typedef int Status; /* Status是函数的类型,其值是函数结果状-1为出现错误1为正常态代码,如OK等 */
typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE 其中1为TRUE 0为FALSE */

typedef int ElemType; /*ElemType是数据的类型,我们这里用int类型表示*/

typedef struct {  //定义单链表的节点类型
    ElemType data;    //数据
    struct LinkNode *next;  //指针域
}LinkNode, *LinkList;

LinkList InitLinkList(LinkList L); //初始化单链表
int LengthLink(LinkList L);//返回单链表的长度
int LocateElemLink(LinkList L, ElemType e);//查找元素e在表中的位置
ElemType GetElemLink(LinkList L, int i);//获取表中第i个位置的元素,并返回
Status InsertLinkList(LinkList L, int i, ElemType e);//在表L中第i个位置插入元素e
Status DeleteElemLink(LinkList L, int i, ElemType *e);//删除表中第i个元素,并用e返回其值
void PrintLinkList(LinkList L);//输出单链表的所有元素
Boolean IsEmptyLink(LinkList L);//判断单链表是否为空
Status DestroyLinkList(LinkList L);//销毁单链表,并释放所占用的空间

  linkList.c函数文件

#include<stdio.h>
#include"linkList.h"

LinkList InitLinkList(LinkList L) {  //初始化单链表
    LinkNode *s;
    s = (LinkList)malloc(sizeof(LinkNode));
    s->next = NULL;
    L = s;
    return L;
}

Status InsertLinkList(LinkList L, int i, ElemType e) { //在表L中第i个位置插入元素e,头插法
    
    LinkList p = L;

    int j = 0;
    while (j < i-1) {
        p = p->next;
        j++;
    }

    LinkNode *newNode = (LinkNode*)malloc(sizeof(LinkNode));
    newNode->data = e;
    newNode->next = p->next;        //新节点指向原来位置节点的下一个
    p->next = newNode;        //原来位置节点指向新节点
    return 1;

}


void PrintLinkList(LinkList L) {  //输出单链表的所有元素
    LinkList p = L;

    p = p->next;
    if (p == NULL)
        printf("链表为空");
    else {
        while (p != NULL) {
            printf(" %d ", p->data);
            p = p->next;
        }
    }
}

int LengthLink(LinkList L) {  //返回单链表的长度
    int i = 0;
    LinkList p = L;

    p = p->next;

    while (p != NULL) {
        i++;
        p = p->next;
    }
    return i;
}

int LocateElemLink(LinkList L, ElemType e) {        //查找元素e在表中的位置
    LinkList p = L;
    int i = 0;

    while (p->next != NULL) {
        p = p->next;
        if (p->data == e)
            return i + 1;
        i++;
    }

    return -1;
    
}

ElemType GetElemLink(LinkList L, int i) {        //获取表中第i个位置的元素,并返回
    LinkList p = L;
    int j = 0;
    
    if (i <= 0 || i > LengthLink(L))
        return NULL;
    
        while (p != NULL) {
        p = p->next;
        j++;
        if (j == i)
            return p->data;
    }
}

Status DeleteElemLink(LinkList L, int i, ElemType *e) {  //删除表中第i个元素,并用e返回其值

    LinkList p = L;
    LinkNode *n;
    ElemType *temp;
    int j = 0;
    if (i <= 0 || i > LengthLink(L))
        return -1;

    while (p != NULL) {
        if (j == i-1) {
            n = p->next;
            p->next = n->next;
            *e = n->data;
            free(n);
            return 1;
        }
        p = p->next;
        j++;
    }
    return 1;
}

Boolean IsEmptyLink(LinkList L) {  //判断单链表是否为空
    if (L->next == NULL)
        return 1;
    else
        return 0;

}

Status DestroyLinkList(LinkList L) {  //销毁单链表,并释放所占用的空间
    L->next = NULL;
    free(L);
    return 1;
}

main.c主函数文件

#include<stdio.h>
#include"linkList.h"

int main() {
    int i;
    int array[] = { 0,1,2,3,4,5 };
    ElemType e;
    LinkList L = InitLinkList(&L);
    
    for (i = 1; i < 6; i++) {
        InsertLinkList(L, i, array[i]);
    }

    PrintLinkList(L);
    printf("\n");
    printf("链表长度为%d\n",LengthLink(L));
    printf("5在链表中第%d个位置\n", LocateElemLink(L, 5));
    printf("第五个位置的元素为%d\n",GetElemLink(L, 5));
    DeleteElemLink(L, 5, &e);
    printf("删除第二个元素,删除的元素为%d,打印删除之后的表\n",e);
    PrintLinkList(L);
    printf("\n");
    if (IsEmptyLink(L) == 1)
        printf("此表为空\n");
    else
        printf("此表不为空\n");
    printf("销毁线性表");
    if (DestroyLinkList(L) == 1)
        printf("销毁成功!\n");
    else
        printf("销毁失败");
}

 

上一篇:数据结构


下一篇:建立单链表(头插法)