单链表总结 (链表的创建、插入、删除、排序等)

本文中链表都是没有头结点的,即头指针指向的结点就存数据,head==NULL链表为空

        链表就是一种线性表,优点是不用事先知道要开多少空间、有多少数据,插入删除数据快,相对的,缺点就是不能像数组那样直接访问第i个数据,因此不能快速排序。

一、结点

struct node
{
    int data;           //链表中存储的数据
    struct node* next;  //指向下一个结点
};

二、链表的创建

struct node* Creat(int n)  //创建链表  n是数据数
{
    struct node *head=NULL;
    struct node *q=NULL;       //q保存前驱结点
    while(n--)
    {
        struct node* p=(struct node*)malloc(sizeof(struct node)); //创建一个新结点并给该结点开空间
        scanf("%d",&p->data);
        p->next=NULL;                //初始化新结点的next指针
        if(head==NULL)               //head==NULL 则该节点是第一个结点
            head=p;
        else
            q->next=p;                //前一个结点的next指向当前结点
        q=p;                          //让q指向新结点,则下次循环q指向的结点就是前一个结点

    }
    return head;  //返回头指针,没有头指针我们就找不到链表了
};

三、链表的删除

1.按值删除,删除所有值为x的结点

struct node* Delete(struct node* head,int x)  //x是要删除的值
{
    while(head!=NULL&&head->data==x) //把前面的值为x的结点删除
        head=head->next;
    if(head==NULL)                   //如果删空了直接return
        return head;
    struct node *q=head;             //前面的x已经删除了,第一个结点一定不等于x,从头结点的下一个结点开始遍历
    while(q!=NULL&&q->next!=NULL)
    {
        if(q->next->data==x)
            q->next=q->next->next;    //删除结点
        q=q->next;
    }
    return head;
};

2.删除第pos个结点

struct node* Delete(struct node* head,int pos)  //删除第pos个点,从0开始计数
{
    if(pos==0)
        return head->next;                    //如果删除第0个 直接返回指向第1个结点的指针
    int num=0;
    struct node *p=head;
    while(p!=NULL&&p->next!=NULL)             //遍历
    {
        num++;
        if(num==pos)                            //当前是第pos个结点,删除并返回
        {
            p->next=p->next->next;
            return head;
        }
        p=p->next;
    }
    return head;                              //循环结束说明链表中结点数小于x,返回头指针
};

四、链表的插入

struct node* Insert(struct node* head,int n,int pos) //在pos位置后插入n
{
    struct node *t=(struct node*)malloc(sizeof(struct node));
    t->data=n;t->next=NULL;           //创建新结点开空间并初始化
    if(pos==0)
    {
        if(head!=NULL)
        {
            t->next=head;
            head=t;
            return head;               //如果pos为0,直接插入并返回
        }
        return t;                      //如果原链表为空链表,直接返回t
    }
    struct node *p=head;
    int num=0;
    while(p!=NULL)
    {
        num++;
        if(num==pos)
        {
            t->next=p->next;
            p->next=t;
            return head;
        }
        p=p->next;
    }
    return head;                     //没有第pos个结点 插入失败
};

五、链表的排序

因为链表的优势就是插入数据快,所以这里写一个插入排序,其他排序就不写了

struct node* Sort(struct node *head)
{
    if(head==NULL)
        return head;
    struct node *Head=head;      //Head是排好序后的链表,将剩下的结点插入到Head链表中
    head=head->next;
    Head->next=NULL;
    while(head!=NULL)
    {
        struct node *t=head;     //t是剩下的结点中的第一个
        head=head->next;
        struct node *q=NULL;     //q指向p的前驱结点
        struct node *p=Head;
        while(p!=NULL&&p->data<t->data)  //在Head链表中找到第一个大于等于t->data的结点
        {
            q=p;
            p=p->next;
        }
        t->next=p;
        if(q==NULL)               //q==NULL说明当前点是最小的,要放在第一个
            Head=t;
        else
            q->next=t;
    }
    return Head;
};

猜你喜欢

转载自blog.csdn.net/qq_39027601/article/details/80229834