• 线性表—单链表的创建、查询、插入、删除、合并


     1 #define ElemType int
     2 #define OK 1
     3 #define ERROR -1
     4 #define Status int
     5 
     6 typedef struct Lnode{
     7     ElemType data;
     8     struct LNode *next;
     9 }LNode, *LinkList;
    10 //LinkList 相当于 LNode *

    遇到的问题

    1.链表传入函数中要真正改变内容要对头节点的指针内容进行修改,  这里要区分开头节点和头节点的指针,

    头节点的指针是LinkList 型的可以存储一个节点的地址,而头节点是一个实实在在的节点,它被头节点的指针索引。

    2.上面定义的     * LinkList  其实和LNode  *    是等价的 ,   所以在开辟节点时候可以直接写:  p = (LinkList)malloc(sizeof(LNode)); 

    两种创建链表的方式:

     1 Status CreatList_L1(LinkList *L, int n)
     2 {
     3     //尾插法创建链表
     4     //要将创建的链表返回,所以要传入指针LinkList *L
     5     LinkList p, q;
     6     q = *L = (LinkList)malloc(sizeof(LNode));
     7     (*L)->next = NULL;
     8     for(int i=0; i < n; i++)
     9     {
    10         p = (LinkList)malloc(sizeof(LNode));
    11         scanf("%d", &p->data);
    12         q->next = p;
    13         q = p;
    14     }
    15     p->next = NULL;
    16     return OK;
    17 }//CreatList_L1
     1 Status CreatList_L2(LinkList *L, int n)
     2 {
     3     //头插法创建链表
     4     (*L) = (LinkList)malloc(sizeof(LNode));
     5     (*L) ->next = NULL;         //头插法一定加上这句
     6     LinkList s;
     7     for(int i=0; i < n; i++)
     8     {
     9         s = (LinkList)malloc(sizeof(LNode));//生成新节点
    10         scanf("%d",&s->data);
    11         s->next = (*L)->next;   //将新开辟的节点查到头节点后面
    12         (*L)->next = s;
    13     }
    14     return OK;
    15 }//CreatList_L2

    查询链表第i个位置的元素,并返回其值:

     1 Status GetElem_L(LinkList L, int i, ElemType *e)
     2 {
     3     //L为带头节点的单链表的头指针
     4     //但第i个元素存在时,其值赋给e并返回OK,否则返回ERROR
     5     LinkList p = L;   //初始化,p指向第1个节点
     6     int j = 0;        //计数器
     7     while(p && j < i) //顺时针向后查找,直到p指向第i个元素或p为空
     8     {
     9         p = p->next;
    10         j++;
    11     }
    12     if(!p || j > i)   //第i个元素不存在
    13         return ERROR;
    14     *e = p->data;      //取第i个元素
    15     return OK;
    16 }//GetElem_L

    插入:

     1 Status ListInsert_L(LinkList L, int i, ElemType e)
     2 {
     3     //在带头节点的单链线性表L第i个位置之前插入元素e
     4     LinkList p = L, s;
     5     int j = 0;
     6     while(p && j < i-1)    //寻找第i个节点,并令p指向其前驱
     7     {
     8         p = p->next;
     9         j++;
    10     }
    11     if(!p || j > i - 1)    //i小于1或着大于表长+1
    12         return ERROR;
    13     s = (LinkList)malloc(sizeof(LNode));  //生成新节点
    14     s->data = e;                          //给新节点赋值
    15     s ->next = p->next;                   //新节点指向第i个节点
    16     p->next = s;                          //第i-1个节点指向新节点
    17     return OK;
    18 }//ListInsert_L

    删除:

     1 Status ListDelete_L(LinkList L, int i, ElemType *e)
     2 {
     3     //在带头节点的单链线性表L中,删除第i个元素,并由e返回其值
     4     LinkList p = L, q;
     5     int j = 0;
     6     while(p && j < i-1)    //寻找第i个元素,并令p指向其前驱
     7     {
     8         p  = p->next;
     9         j++;
    10     }
    11     if(!p || j > i-1)       //删除位置不合理
    12         return ERROR;
    13     q = p->next;            //q指向删除节点
    14     *e = q->data;           //e保存其值
    15     p -> next = q->next;    //移动指针跳过该节点
    16     free(q);                //释放空间
    17     return OK;
    18 }//ListDelete_L

    合并:

     1 void MergeList_L(LinkList La, LinkList Lb, LinkList *Lc)
     2 {
     3     //已知单链线性表La和Lb的元素按值非递减排列
     4     //归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列
     5     LinkList pa = La->next;
     6     LinkList pb = Lb->next;
     7     (*Lc) = La;             //用La的头节点作为Lc的头节点
     8     LinkList pc = *Lc;
     9     while(pa && pb)      //与顺序表类似
    10     {
    11         if(pa->data <= pb->data)
    12         {
    13             pc->next = pa;
    14             pc = pa;
    15             pa = pa->next;
    16         }
    17         else
    18         {
    19             pc->next = pb;
    20             pc = pb;
    21             pb = pb->next;
    22         }
    23     }
    24     pc->next = pa ? pa : pb;  //插入剩余段
    25     free(Lb);                 //释放Lb的头节点
    26 }//MergeList_L

    下面是完整代码,可以试一下:

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 
      4 #define ElemType int
      5 #define OK 1
      6 #define ERROR -1
      7 #define Status int
      8 
      9 typedef struct Lnode{
     10     ElemType data;
     11     struct LNode *next;
     12 }LNode, *LinkList;
     13 //LinkList 相当于 LNode *
     14 
     15 Status CreatList_L1(LinkList *L, int n)
     16 {
     17     //尾插法创建链表
     18     //要将创建的链表返回,所以要传入指针LinkList *L
     19     LinkList p, q;
     20     q = *L = (LinkList)malloc(sizeof(LNode));
     21     (*L)->next = NULL;
     22     for(int i=0; i < n; i++)
     23     {
     24         p = (LinkList)malloc(sizeof(LNode));
     25         scanf("%d", &p->data);
     26         q->next = p;
     27         q = p;
     28     }
     29     p->next = NULL;
     30     return OK;
     31 }//CreatList_L1
     32 
     33 Status CreatList_L2(LinkList *L, int n)
     34 {
     35     //头插法创建链表
     36     (*L) = (LinkList)malloc(sizeof(LNode));
     37     (*L) ->next = NULL;         //头插法一定加上这句
     38     LinkList s;
     39     for(int i=0; i < n; i++)
     40     {
     41         s = (LinkList)malloc(sizeof(LNode));//生成新节点
     42         scanf("%d",&s->data);
     43         s->next = (*L)->next;   //将新开辟的节点查到头节点后面
     44         (*L)->next = s;
     45     }
     46     return OK;
     47 }//CreatList_L2
     48 
     49 Status GetElem_L(LinkList L, int i, ElemType *e)
     50 {
     51     //L为带头节点的单链表的头指针
     52     //但第i个元素存在时,其值赋给e并返回OK,否则返回ERROR
     53     LinkList p = L;   //初始化,p指向第1个节点
     54     int j = 0;        //计数器
     55     while(p && j < i) //顺时针向后查找,直到p指向第i个元素或p为空
     56     {
     57         p = p->next;
     58         j++;
     59     }
     60     if(!p || j > i)   //第i个元素不存在
     61         return ERROR;
     62     *e = p->data;      //取第i个元素
     63     return OK;
     64 }//GetElem_L
     65 
     66 Status ListInsert_L(LinkList L, int i, ElemType e)
     67 {
     68     //在带头节点的单链线性表L第i个位置之前插入元素e
     69     LinkList p = L, s;
     70     int j = 0;
     71     while(p && j < i-1)    //寻找第i个节点,并令p指向其前驱
     72     {
     73         p = p->next;
     74         j++;
     75     }
     76     if(!p || j > i - 1)    //i小于1或着大于表长+1
     77         return ERROR;
     78     s = (LinkList)malloc(sizeof(LNode));  //生成新节点
     79     s->data = e;                          //给新节点赋值
     80     s ->next = p->next;                   //新节点指向第i个节点
     81     p->next = s;                          //第i-1个节点指向新节点
     82     return OK;
     83 }//ListInsert_L
     84 
     85 Status ListDelete_L(LinkList L, int i, ElemType *e)
     86 {
     87     //在带头节点的单链线性表L中,删除第i个元素,并由e返回其值
     88     LinkList p = L, q;
     89     int j = 0;
     90     while(p && j < i-1)    //寻找第i个元素,并令p指向其前驱
     91     {
     92         p  = p->next;
     93         j++;
     94     }
     95     if(!p || j > i-1)       //删除位置不合理
     96         return ERROR;
     97     q = p->next;            //q指向删除节点
     98     *e = q->data;           //e保存其值
     99     p -> next = q->next;    //移动指针跳过该节点
    100     free(q);                //释放空间
    101     return OK;
    102 }//ListDelete_L
    103 
    104 void MergeList_L(LinkList La, LinkList Lb, LinkList *Lc)
    105 {
    106     //已知单链线性表La和Lb的元素按值非递减排列
    107     //归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列
    108     LinkList pa = La->next;
    109     LinkList pb = Lb->next;
    110     (*Lc) = La;             //用La的头节点作为Lc的头节点
    111     LinkList pc = *Lc;
    112     while(pa && pb)      //与顺序表类似
    113     {
    114         if(pa->data <= pb->data)
    115         {
    116             pc->next = pa;
    117             pc = pa;
    118             pa = pa->next;
    119         }
    120         else
    121         {
    122             pc->next = pb;
    123             pc = pb;
    124             pb = pb->next;
    125         }
    126     }
    127     pc->next = pa ? pa : pb;  //插入剩余段
    128     free(Lb);                 //释放Lb的头节点
    129 }//MergeList_L
    130 
    131 int main()
    132 {
    133     int n;
    134     LinkList L, p, s;
    135     scanf("%d",&n);
    136     CreatList_L1(&L, n);
    137     printf("
    ~~~
    ");
    138     p = L->next;
    139     while( p != NULL){
    140         printf("%d ",p->data);
    141         p = p->next;
    142     }
    143     printf("
    ");
    144 
    145     int i, e;
    146     printf("查询位置: ");
    147     scanf("%d",&i);
    148     GetElem_L(L, i, &e);
    149     printf("e == %d
    ",e);
    150 
    151     printf("插入位置、元素:");
    152     scanf("%d%d",&i,&e);
    153     ListInsert_L(L, i, e);
    154     p = L->next;
    155     while(p){
    156         printf("%d ",p->data);
    157         p = p->next;
    158     }
    159     printf("
    ");
    160 
    161     printf("删除位置:");
    162     scanf("%d",&i);
    163     ListDelete_L(L, i, &e);
    164     printf("e == %d
    ",e);
    165 
    166     int a[ ]= {3, 5, 8, 11};
    167     int b[ ]= {2, 6, 8, 9, 11, 15, 20};
    168     LinkList La, Lb;
    169     La = (LinkList)malloc(sizeof(LNode));
    170     Lb = (LinkList)malloc(sizeof(LNode));
    171     La->next = Lb->next = NULL;
    172     p = La;
    173     for(int i = 0; i < sizeof(a)/sizeof(a[0]); i++)
    174     {
    175         s = (LinkList)malloc(sizeof(LNode));
    176         s->data = a[i];
    177         p->next = s;
    178         p = s;
    179     }
    180     p->next = NULL;
    181 
    182     p = Lb;
    183     for(int i = 0; i<sizeof(b)/sizeof(b[0]); i++)
    184     {
    185         s = (LinkList)malloc(sizeof(LNode));
    186         s->data = b[i];
    187         p->next = s;
    188         p = s;
    189     }
    190     p->next = NULL;
    191 
    192     printf("La = ");
    193     p = La->next;
    194     while(p)
    195     {
    196         printf("%d ",p->data);
    197         p = p->next;
    198     }
    199     printf("
    ");
    200     p = La->next;
    201 
    202     printf("Lb = ");
    203     p = Lb->next;
    204     while(p)
    205     {
    206         printf("%d ",p->data);
    207         p = p->next;
    208     }
    209     printf("
    ");
    210 
    211     LinkList Lc;
    212     MergeList_L(La, Lb, &Lc);
    213 
    214     printf("MergeList = ");
    215     p = Lc->next;
    216     while(p)
    217     {
    218         printf("%d ", p->data);
    219         p = p->next;
    220     }
    221     printf("
    ");
    222 
    223 
    224     return 0;
    225 }
    View Code
  • 相关阅读:
    颜色空间之CIE2000色差公式
    爱做梦的人-人的特性之一
    Lua文件操作和串行化
    Lua文件操作和串行化
    Lua调用C++带参数的方法
    Lua调用C++带参数的方法
    C++对Lua中table进行读取、修改和创建
    C++对Lua中table进行读取、修改和创建
    C++获取Lua全局变量和执行Lua多参数多返回值函数
    C++获取Lua全局变量和执行Lua多参数多返回值函数
  • 原文地址:https://www.cnblogs.com/Dawn-bin/p/9516718.html
Copyright © 2020-2023  润新知