单链表的创建、插入、删除、排序以及逆置

单链表的创建、插入、删除、排序以及逆置

       链表中的数据是以节点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。

下面将给出单链表的创建、插入、删除、排序以及逆置的思想和代码。

(一)单链表的创建及输出

(1),链表节点的数据结构定义

typedef struct student //定义链表数据结构
{
            intdata;
            structstudent *next;
}node;


(2)链表的创建

     1 ) 定义链表的数据结构;

     2 ) 创建一个空表;

     3 ) 利用malloc ( )函数向系统申请分配一个节点;

     4 ) 将新节点的指针成员赋值为空。若是空表,将新节点连接到表头;若是非空表,将新

         节点接到表尾;

     5 ) 判断一下是否有后续节点要接入链表,若有转到3 ),否则结束;

//链表的创建
node *createnode()
{
       node *head, *p, *s;
       int x, flag = 1;
       head =(node*)malloc(sizeof(node));
       p = head;
       while (flag)
       {
              printf("\n Pleaseinput the data:");
              scanf_s("%d",&x);
              if (x != 0)
              {
                    s =(node*)malloc(sizeof(node));
                    s->data = x;
                    printf("\n%d", s->data);
                    p -> next = s;
                    p = s;
              }
              else flag = 0;
       }
       head = head->next;
       p->next = NULL;
       printf("\n  %d", head->data);
       return head;
}


(3)单链表的输出过程有以下几步

1) 找到表头;

2) 若是非空表,输出节点的值成员,是空表则退出;

3 ) 跟踪链表的增长,即找到下一个节点的地址;

4) 转到2 ).

代码如下:

void print(node *head)
{
        node *p;
        int n = length(head);
        printf("\n These %drecords are :\n", n);
        p = head;
        if (head != NULL)
        {
               while (p != NULL)
               {
                       printf("\n%d ", p->data);
                       p =p->next;
               }
        }
}


(二)单链表的插入

         单链表的插入,如下图所示


         如果插入节点在头节点以前,则p0的next指向p1,头节点指向p0,如下图所示。


         如果插入中间节点,如下图所示。


         则先让p2的next指向p0,再让p0指向p1,如下图所示。


         如果插入尾结点,如下图所示。


         则先让p1的next指向p0,再让p0指向空,如下图所示


        完整代码如下:

//单链表插入
node *insert(node *head, int num)
{
        node *p0, *p1, *p2=NULL;
        p1 = head;
        p0 =(node*)malloc(sizeof(node));
        p0->data = num;
        //找到合适的插入元素位置
        while (p0->data >p1->data&&p1->next != NULL)
        {
               p2 = p1;
               p1 = p1->next;
        }
        if (p0->data <= p1->data)
        {
               //在头节点前插入元素
               if (p1 == head)
               {
                       p0->next =p1;
                       head = p0;
               }
               //在中间节点插入元素
               else
               {
                       p2->next =p0;
                       p0->next =p1;
               }
        }
        //尾结点插入元素
        else
        {
               p1->next = p0;
               p0->next = NULL;
        }
        return head;
}


(三)单链表的删除

     如果删除的是头节点,如下图所示


     则把head指针指向头节点的下一个节点,同时free p1,如下图所示。


        如果删除的中间节点,如下图所示


       则用p2的next指向p1的next的同时,free p1,如下图所示


    代码如下:

//单链表删除
node *del(node *head, int num)
{
        node *p1, *p2=NULL;
        p1 = head;
        //找到删除节点或遍历完链表未找到时退出循环
        while (num !=p1->data&&p1->next != NULL)
        {
               p2 = p1;
               p1 = p1->next;
        }
        if (num == p1->data)
        {
               //删除的是头节点
               if (p1 == head)
               {
                       head =p1->next;
                       free(p1);
               }
               //删除中间节点,将前节点后继指向该节点后继
               else
                       p2->next =p1->next;
        }
        else
        {
               printf("%d cann'tbeen found in list", num);
        }
        return head;
}


(四)单链表排序

       此处给予简单的基于冒泡排序的链表排序代码,如下

//单链表排序,冒泡方法
node *sort(node *head)
{
        node *p;
        int n = length(head);
        int temp = 0;
        if (head == NULL ||head->next == NULL)
               return head;
        p = head;
        for (int i = 1; i < n;i++)
        {
               p = head;
               for (int j = 0; j <n - i; j++)
               {
                       if(p->data>p->next->data)
                       {
                               temp =p->data;
                               p->data= p->next->data;
                               p->next->data= temp;
                       }
                       p =p->next;
               }
        }
        return head;
}


(五)单链表逆置(时间复杂度为O(n))

    解析:单链表模型如下。

          进行单链表逆置,首先要让p2的next指向p1,如下图所示。


          再由p1指向p2,p2指向p3,如下图所示


         代码如下:

//时间复杂度为O(n) 的单链表逆置
node *reverse(node *head)
{
        node *p1, *p2, *p3;
        if (head == NULL ||head->next == NULL)
               return head;
        p1 = head;
        p2 = p1->next;
        while (p2)
        {
               p3 = p2->next;
               p2->next = p1;
               p1 = p2;
               p2 = p3;
        }
        head->next = NULL;
        head = p1;
        return head;
}


 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值