zoukankan      html  css  js  c++  java
  • c语言实现--不带头结点的单链表操作

    1,不带头结点的单链表操作中,除了InitList(),GetElem(),ListInsert(),ListDelete()操作与带头结点的单链表有差别外,其它的操作基本上一样。

    2,不带头结点单链表示意图:

    链表指针直接指向了首元节点,因此在首元节点前插入数据元素或者删除首元节点元素都会改变头指针的值。

    3,不带头结点的单链表定义及操作集合,除了插入,删除,清空操作需要传递头指针的地址外,基本上一样。头文件defs.h

     1 #ifndef _DEFS_H_
     2 #define _DEFS_H_
     3 
     4 #include<stdio.h>
     5 #include<malloc.h>  //malloc(),free()
     6 #include<stdlib.h>  //exit()
     7 
     8 struct LNode
     9 {
    10     int data;
    11     int * next;
    12 };
    13 typedef struct LNode * linklist;
    14 
    15 //操作集合,注意ClearList,ListInsert,ListDelete
    16 void InitList(linklist *L);
    17 void DestroyList(linklist *L);
    18 void ClearList(linklist *L);   //这里,清空和撤销一样
    19 void ListEmpty(linklist L);
    20 int ListLength(linklist L);
    21 int GetElem(linklist L, int i, int *e);
    22 int LocateElem(linklist L, int e);
    23 int PriorElem(linklist L, int cur_e, int *pri_e);
    24 int NextElem(linklist L, int cur_e, int *nex_e);
    25 int ListInsert(linklist *L, int i, int e); //注意在首元结点前插入时改变头指针
    26 int ListDelete(linklist *L, int i, int *e); //删除首元结点时改变头指针
    27 void TravelList(linklist L);
    28 #endif  //只要是能够改变头指针的值,均是传递头指针的地址

    4,InitList操作。其不需要分配结点,直接令头指针为空

    1 #include"defs.h"
    2 
    3 void InitList(linklist *L)
    4 {
    5     (*L) = NULL;   //*L即表示头指针
    6 }
    InitList.c

    5,DestroyList操作.其就是释放所有结点。

     1 #include"defs.h"
     2 
     3 void DestroyList(linklist *L)
     4 {
     5      linklist p;    //p为移动指针
     6     while (*L)
     7     {
     8         p = (*L)->next;  //释放某一结点时,需保存其下一个结点的地址
     9        free(*L);
    10         *L = p;
    11     }
    12 }
    DesroyList.c

    6,ClearList操作。其意思和撤销一样,释放所有结点.(带头结点的清空,保留了头结点)

     1 #include"defs.h"
     2 
     3 void ClearList(linklist *L)
     4 {
     5     linklist p;
     6     while (*L)
     7     {
     8         p = (*L)->next;
     9         free(*L);
    10         *L = p;
    11     }
    12 }
    ClearList.c

    7,ListEmpty操作.判断链表是否为空。

    1 #include"defs.h"
    2 
    3 void ListEmpty(linklist L)
    4 {
    5     if (L)  //L不为空
    6         printf("链表不为空。
    ");
    7     else
    8         printf("链表为空.
    ");
    9 }
    ListEmpty.c

    8,ListLength操作。求链表的长度,需要从第一个结点开始遍历。

     1 #include"defs.h"
     2 
     3 int ListLength(linklist L)
     4 {
     5     int j = 0;  //作为计数器
     6    linklist p = L;
     7     while (p)
     8     {
     9         ++j;
    10         p = p->next;
    11     }
    12     return j;
    13 }
    ListLength.c

    9,GetElem操作。需要判断元素位置的合法性。

     1 #include"defs.h"
     2 
     3 int GetElem(linklist L, int i, int *e)
     4 {
     5     int j = 1; //j记第一个结点开始
     6    linklist p = L; 
     7 
     8     if (i<1)   //位置不合法
     9         exit(0);
    10     while (p && j<i)   //找到第i个结点
    11     {
    12         ++j;
    13         p = p->next;
    14     }
    15     if (j==i && p)  //判断第i个位置元素是否存在,同时也解决了i = 1的情况
    16         *e = p->data;
    17 
    18     return 0;
    19 }
    GetElem.c

    10,LocateElem操作。需要从表一个结点遍历。查找成功返回其位置值,失败则返回-1

     1 #include"defs.h"
     2 
     3 int LocateElem(linklist L, int e)
     4 {
     5     linklist p = L;
     6     int j = 0;
     7 
     8     while (p)
     9     {
    10         ++j;
    11         if (p->data == e)
    12             return j;
    13         p = p->next;   //更新p
    14     }
    15     return -1;   //查找失败,返回-1
    16 }
    LocateElem.c

    11,PriorElem操作。

     1 #include"defs.h"
     2 
     3 int PriorElem(linklist L, int cur_e, int *pri_e)
     4 {
     5     linklist p = L;
     6     linklist q;
     7 
     8     while (p)
     9     {
    10         q = p->next;   //q指向p的后继
    11         if (q && q->data == cur_e) //q存在,且q的数据和当前值相等
    12         {
    13             *pri_e = p->data;    //p即为q前驱
    14             return 0;
    15         }
    16         p = q;          //更新p
    17     }
    18 
    19     return 0;
    20 }
    PriorElem.c

    12,NextElem操作。 求前驱与后继的操作,基本一样。两个指针。

     1 #include"defs.h"
     2 
     3 int NextElem(linklist L, int cur_e, int *nex_e)
     4 {
     5     linklist p = L;
     6     linklist q;
     7 
     8     while (p)
     9     {
    10         q = p->next;  //q指向p的后继
    11         if (q && p->data == cur_e) //q存在且p的数据与当前值相等
    12         {
    13             *nex_e = q->data;  //q即为p的后继
    14             return 0;
    15         }
    16         p = q;
    17     }
    18     return 0;
    19 }
    NextElem.c

    13,ListInsert操作。

     1 #include"defs.h"
     2 
     3 int ListInsert(linklist *L, int i, int e)
     4 {
     5     int j = 1;  //j从1开始计数
     6     linklist p = *L;
     7     linklist q, s;
     8    
     9     if (i<1)   //位置不合理
    10         exit(0);
    11     
    12     s = (linklist)malloc(sizeof(struct LNode));
    13     s->data = e;
    14     
    15     if (i==1)
    16     {
    17         s->next = p;
    18         *L = s;
    19     }
    20     else 
    21     {
    22         while (p && j<i-1)  //找到第i-1个结点
    23       {
    24             ++j;
    25             p = p->next;
    26         }
    27         if (p)
    28         {
    29              q = p->next;   //q指向第i个结点,q可以为空
    30           s->next = q;
    31              p->next = s;
    32         }
    33     }
    34     return 0;
    35 }
    ListInsert.c

    14,ListDelete操作。

     1 #include"defs.h"
     2 
     3 int ListDelete(linklist *L, int i, int *e)
     4 {
     5     int j = 1;
     6     linklist p = *L;
     7     linklist q;
     8 
     9     if (*L == NULL)  //链表为空
    10        exit(0);
    11     if (i==1)
    12     {
    13         q = p->next;  //q指向p的后继,保存后一个地址
    14       free(*L);
    15         *L = q;
    16     }
    17     else 
    18     {
    19         while (p && j<i-1) //找到第i-1个位置
    20       {
    21             ++j;
    22             p = p->next;
    23         }
    24         q = p->next;  //q指向第i个位置
    25         if (!q || i<1)  //第i个位置不存在
    26             exit(0);
    27         p->next = q->next;  //p指向第i+1个位置
    28       free(q);  //释放第i个结点
    29     }
    30 
    31 }
    ListDelete.c

    15,TravelList操作。

     1 #include"defs.h"
     2 
     3 void TravelList(linklist L)
     4 {
     5     int j = 0;
     6     linklist p = L;
     7     while (p)
     8     {
     9         ++j;
    10         printf("第%d个结点值为: %d
    ", j, p->data);
    11         p = p->next;   //更新p
    12     }
    13 }
    TravelList.c

    16,main.c测试代码里,初始插入时应该从第一个位置开始插入。(初始时为空表)
    17,makefile文件。

     1 object : main.o InitList.o DestroyList.o ClearList.o ListEmpty.o 
     2 ListLength.o GetElem.o LocateElem.o PriorElem.o NextElem.o 
     3 ListInsert.o ListDelete.o TravelList.o
     4 
     5 test : $(object)
     6         gcc -g -Wall -o test $(object)
     7 
     8 $(object) : defs.h
     9 
    10 .PHONY : clean
    11 clean :
    12         rm -f *.o 
    makefile
  • 相关阅读:
    JavaWeb学习(17):优化三层(加入接口和 DBUtil)
    [每日一题]:The Lazy Cow(silver)
    JavaWeb学习(16): 三层架构模式实现简单的学生管理系统(内含数据库)
    BZOJ3275Number——二分图最大权独立集
    BZOJ3438小M的作物——最小割
    BZOJ2127happiness——最小割
    BZOJ3894文理分科——最小割
    BZOJ2150部落战争——最小路径覆盖
    BZOJ4205卡牌配对——最大流+建图优化
    BZOJ4032[HEOI2015]最短不公共子串——序列自动机+后缀自动机+DP+贪心
  • 原文地址:https://www.cnblogs.com/rookiefly/p/3436911.html
Copyright © 2011-2022 走看看