编程语言

img zjx624bjh

单链表基础篇

发表于2017/9/25 20:47:33  211人阅读

分类: c语言

首先来说说顺序表和单链表的区别:
顺序表
顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构。
顺序表空间是连续的,便于随机访问,在不增容的情况下,尾插的效率高,头插和中间插入不容易实现,增容的代价较高,但其cpu利用率相比链表较高。
单链表
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。
一次只开辟一个结点的空间,用来存储当前要保存的数据及指向下一个结点或NULL的指针,所以单链表的空间大小时动态变化的。
链表中的每个节点通过链或指针连接在一起,程序通过指针访问链表中的节点。不支持随机访问。

接下来,我们来了解一些单链表的基本操作!
1.单链表的数据结构

#pragma once//防止头文件被重复引用
typedef int DataType;

typedef struct Node//定义结构体
{
    DataType data;//定义数据
    struct Node* next;//指向下一个节点的指针
}Node;

2.建立节点

Node* BuyNode(DataType x)
{
    Node* node=(Node*)malloc(sizeof(Node));//用malloc函数动态开启一块空间
    node->data=x;
    node->next=NULL;
    return node;
}

3.打印单链表

void PrintList(Node* pHead)
{
    Node* cur=pHead;
    while(cur)
    {
        printf("%d ",cur->data);
        cur=cur->next;
    }
    printf("%\n ");
}

4.在单链表的尾部插入节点
这里写图片描述

void PushBack(Node** ppHead, DataType x)
{
    if(*ppHead==NULL)//如果链表为空,直接放入新节点
    {
        *ppHead=BuyNode(x);
    }
    else
    {
        Node* tail=*ppHead;
        while(tail->next!=NULL)
        {
            tail=tail->next;
        }
        tail->next=BuyNode(x);
    }
}
测试代码:
void Test()
{
    Node*pos;
    Node*list=NULL;
    PushBack(&list,1);
    PushBack(&list,2);
    PushBack(&list,3);
    PushBack(&list,4);
    PrintList(list);
    }

5.删除一个单链表的尾部节点
这里写图片描述

void PopBack(Node** ppHead)
{
    if(*ppHead==NULL)//空链表
    {
        return;
    }
    else if((*ppHead)->next==NULL)//只有一个节点
    {
        free(*ppHead);
        *ppHead=NULL;
    }
    else
    {
        Node* cur=* ppHead;
        Node* prev = NULL;
        while(cur->next)
        {
            prev=cur;
            cur=cur->next;
        }
        prev->next=NULL;
        free(cur);
    }
}
测试代码
void Test()
{
    Node*pos;
    Node*list=NULL;
    PushBack(&list,1);
    PushBack(&list,2);
    PushBack(&list,3);
    PushBack(&list,4);
    PrintList(list);
    PopBack(&list);
    PrintList(list);
}

6.在单链表指定位置pos前插入一个节点
这里写图片描述

void Insert(Node** ppHead,Node* pos, DataType x)
{
    assert(pos);
    if(pos==NULL)
    {
        PushFront(ppHead,x);
    }
    else
    {
        Node* tmp=BuyNode(x);
        Node* prev=*ppHead;
        while(prev->next!=pos)
        {
            prev=prev->next;
        }
        prev->next=tmp;
        tmp->next=pos;
    }
}
测试代码:
void Test()
{
    Node*pos;
    Node*list=NULL;
    PushBack(&list,1);
    PushBack(&list,2);
    PushBack(&list,3);
    PrintList(list);
    pos=list;
        pos=pos->next;
    Insert(&list,pos,30);
    PrintList(list);
}

7.删除一个无头单链表的非尾节点
无头单链表不知道头节点的地址,所以找不到要删除节点的位置,换个思路可以将问题转化为:
1>记下要删除节点pos的下一个节点next;
2>将next节点的数据赋给pos节点
3>让pos的下一个节点指向next的下一个节点;
4>最后free掉next即可。
这里写图片描述

void EarseNoTail(Node* pos)
{
    Node* next;
    assert(pos&&pos->next);
    next=pos->next;
    pos->data=next->data;
    pos->next=next->next;
    free(next);
}
阅读全文
0 0

相关文章推荐

img
取 消
img