C语言链表操作功能实现详解心得

今天将给大家讲述链表的学习心得。学习数据结构,毋庸置疑链表必须学好,后面的栈、队列、树、图都是以链表为基础的;链表的种类很多,有单链表、双链表、循环链表、非循环链表;在此,我们以非循环单链表为例,来讲链表的创建、求长度、排序、插入和排序。

1.什么是链表

     链表我的理解要包含以下特征:(1).由n个节点离散分配;(2).每个节点通过指针连接(3)每一个节点由一个前驱节点和一个后驱节点(4).首节点没有前驱节点,尾节点没有后驱节点;

     满足上面的4条,我们就称为链表;链表既然由很多个节点,那节点又由什么组成?节点由两个部分组成,一是数据域,用来存放有效数据;二是指针域,用来指向下一个节点;下面用C语言来构建链表数据结构,首先应该构造出节点,然后再把所有的节点连起来,就构成了链表;

(1)节点的构造

        

[cpp]  view plain  copy
  1. typedef struct Node  
  2. {  
  3.     int data;//数据域,用来存放数据域;  
  4.     struct Node *pNext;//定义一个结构体指针,指向下一次个与当前节点数据类型相同的节点  
  5. }NODE,*PNODE;  //NODE等价于 struct Node; PNODE等价于struct Node *; 此处用大写是为了与变量区分,可以让人容易变出是个数据类型  
    typedef 只是给数据类型取个别名,即 typedef  数据类型  别名;我们知道struct Node 是我们定义的数据类型;

(2)链表的创建

     在创建链表之前,我们需要需要了解一下专业术语:

   首节点:存放第一个有效数据的节点;

   尾节点:存放最后一个有效数据的节点;

   头节点:头节点的数据类型与首节点的数据类型相同,并且头节点是首节点前面的那个节点,并不存放有效数据;头节点的存在只是为了方便链表的操作。

   头指针:指向头节点的指针;

   尾指针:指向尾节点的指针;

首先,我们应该创建一个头节点,并用头指针指向它,用C语言描述:用malloc向计算机申请一块内存,并定义一个指向与头节点数据类型相同的指针(一定要判断申请内存是否成功);

然后,要知道要创建链表的长度,用一个循环来每次创建一个节点,并把每个节点连在一起;

  

假如我们要在头节点phead后面插入节点p:

(1)把头节点的指针域指向P节点,即pHead->pNext=p;

(2)把p节点的指针域指向NULL,即p->pNext=NULL;

这样就可以了吗? 想想我们就可以发现,当我们要插入多个节点时,头节点始终指向最后添加的一个数据,以前的节点通过头指针此时已经找不到了;我们定义一个尾指针pTail,始终用来指向链表的结尾,每次只在pTail后面添加节点。

伪算法:

(1)定义一个尾指针pTail,并初始化,使它指向头节点,即pTail=pHead;

(2)在pTail后面添加节点,修改指针: 

       pTail->pNext=p;  

      p->pNext=NULL;

      pTail=p;              //使pTail指向链表最后一个元素

[cpp]  view plain  copy
  1. PNODE Create_List(void)  
  2. {  
  3.     int len;  //存放链表的长度  
  4.     int i;   //循环变量  
  5.     int val;//用来临时存放用户输入的结点的值  
  6.     PNODE List;  
  7.     PNODE pHead=(PNODE)malloc(sizeof(NODE));//分配一个头节点  
  8.     if(NULL==pHead)  
  9.     {  
  10.         printf("Memory allocation failure");  
  11.         exit(-1);  
  12.     }  
  13.     else  
  14.     {   PNODE pTail=pHead;  
  15.         pHead->pNext=NULL;   
  16.         printf("please input the length of list: ");  //需要一个指针始终指向链表的结尾  
  17.         scanf("%d",&len);  
  18.         for(i=0;i<len;i++)  
  19.         {  
  20.             PNODE p=(PNODE)malloc(sizeof(NODE));  
  21.             if(NULL==p)  
  22.             {  
  23.                 printf("Memory allocation failure");  
  24.                 exit(-1);  
  25.             }  
  26.             else  
  27.             {     
  28.                 printf("please input the value of list: ");  
  29.                 scanf("%d",&val);  
  30.                 p->data=val;  
  31.                 pTail->pNext=p;  
  32.                 p->pNext=NULL;  
  33.                 pTail=p;  
  34.             }  
  35.   
  36.         }  
  37.   
  38.   
  39.     }  
  40.     return pHead;  
  41.   
  42. }  

2.向链表中插入元素


假如要在节点2的前面插入节点p,我们首先要找到节点2的前驱节点1,假设现在q指针指向节点1,则

(1)p->pNext=q->pNext;

(2)q->pNext=p;

程序代码如下:

[cpp]  view plain  copy
  1. //链表的第pos有效元素前面插入元素val,首先我们应该找到第pos个元素前面一个元素的位置;  
  2. //当链表有3个元素时,pos=4,将不会进行插入操作  
  3. bool Insert_List(PNODE pHead,int pos,int val)  
  4. {  
  5.     int i=0;  
  6.     PNODE p=pHead;  
  7.     while((NULL!=p)&&(i<pos-1)) //  
  8.     {  
  9.         p=p->pNext;  
  10.         i++;  
  11.     }  
  12.     if(p==NULL||i>pos-1)  //把链表为空的情况考虑进去了;i>pos-1 可以防止用户输入错误;  
  13.         return false;  
  14.   
  15.     //程序执行到这之后,i=pos-1;p指针指向链表第pos个有效节点的前驱,即指向第pos-1节点;  
  16.     PNODE q=(PNODE)malloc(sizeof(NODE));  
  17.     q->data=val;  
  18.     q->pNext=p->pNext;  
  19.     p->pNext=q;  
  20.   
  21.   
  22. }  


3.删除链表中的元素


假如要删除节点2,只需要把节点1指针域指针指向节点3,但不要忘记释放节点2所占的内存,否则将会造成内存泄漏;首先必须找到节点2的前驱节点1,假设p指向节点1。

(1)q=p->pNext;   //首先用q保存要删除节点的地址;

(2)p->pNext=q->pNext;   //q->pNext=p->pNext->pNext;   修改指针使节点1指向节点3;

(3)free(q);  //释放节点2所占的内存;

[cpp]  view plain  copy
  1. bool Delete_List(PNODE pHead,int pos,int *val)  
  2. {  
  3.     int i=0;  
  4.     PNODE p=pHead;  
  5.     while((NULL!=p)&&(i<pos-1))  
  6.     {  
  7.         p=p->pNext;  
  8.         i++;  
  9.     }  
  10.     if(p==NULL||i>pos-1)  //把链表为空的情况考虑进去了;i>pos-1 可以防止用户输入错误;  
  11.         return false;  
  12.   
  13.     //程序执行到这之后,i=pos-1;  
  14.     PNODE q=p->pNext;  //q指向待删除的节点;  
  15.     *val=q->data;  
  16.     p->pNext=q->pNext; //修改链表指针指向;  
  17.     free(q);           //释放q所指向节点的内存;  
  18.     q=NULL;//千万不可以忘记,否则会出现野指针;  
  19. }  

4.链表元素的排序

快速排序和冒泡排序的思想对于链表这个数据结构同样适用,下面是一个用选择排序来实现链表的排序;

[cpp]  view plain  copy
  1. //链表有效元素的个数  
  2. int Length_List(PNODE pHead)  
  3. {   int len=0;  //定义变量要记得初始化;  
  4.     PNODE p=pHead->pNext;  
  5.     while(NULL!=p)  
  6.     {  
  7.         len++;  
  8.         p=p->pNext;  
  9.     }  
  10.     return len;  
  11.   
  12. }  


[cpp]  view plain  copy
  1. //对链表中的元素进行排序  
  2. void Sort_List(PNODE pHead)  
  3. {  
  4.     int i,j;  
  5.     int temp;  
  6.     int len=Length_List(pHead);  
  7.     PNODE p,q;//指向链表第一个有效元素  
  8.   
  9.     for(i=0,p=pHead->pNext;i<len-1;i++,p=p->pNext)  
  10.     {  
  11.         for(j=i+1,q=p->pNext;j<len;j++,q=q->pNext)  
  12.         {  
  13.             //交换数据  
  14.             if(p->data>q->data)  
  15.             {  
  16.                 temp=p->data;  
  17.                 p->data=q->data;  
  18.                 q->data=temp;  
  19.             }  
  20.         }  
  21.     }  
  22. }  

和数组排序很像,只是这里需要两个指针p、q不停地移动,来获取链表中的数据元素;


#include "stdafx.h"
#include "stdio.h"
#include <stdlib.h>
#include "string.h"
 
typedef int elemType ;
 
/************************************************************************/
/*             以下是关于线性表链接存储(单链表)操作的18种算法        */
 
/* 1.初始化线性表,即置单链表的表头指针为空 */
/* 2.创建线性表,此函数输入负数终止读取数据*/
/* 3.打印链表,链表的遍历*/
/* 4.清除线性表L中的所有元素,即释放单链表L中所有的结点,使之成为一个空表 */
/* 5.返回单链表的长度 */
/* 6.检查单链表是否为空,若为空则返回1,否则返回0 */
/* 7.返回单链表中第pos个结点中的元素,若pos超出范围,则停止程序运行 */
/* 8.从单链表中查找具有给定值x的第一个元素,若查找成功则返回该结点data域的存储地址,否则返回NULL */
/* 9.把单链表中第pos个结点的值修改为x的值,若修改成功返回1,否则返回0 */
/* 10.向单链表的表头插入一个元素 */
/* 11.向单链表的末尾添加一个元素 */
/* 12.向单链表中第pos个结点位置插入元素为x的结点,若插入成功返回1,否则返回0 */
/* 13.向有序单链表中插入元素x结点,使得插入后仍然有序 */
/* 14.从单链表中删除表头结点,并把该结点的值返回,若删除失败则停止程序运行 */
/* 15.从单链表中删除表尾结点并返回它的值,若删除失败则停止程序运行 */
/* 16.从单链表中删除第pos个结点并返回它的值,若删除失败则停止程序运行 */
/* 17.从单链表中删除值为x的第一个结点,若删除成功则返回1,否则返回0 */
/* 18.交换2个元素的位置 */
/* 19.将线性表进行快速排序 */
 
 
/************************************************************************/
typedef struct Node{    /* 定义单链表结点类型 */
    elemType element;
    struct Node *next;
}Node;
 
 
/* 1.初始化线性表,即置单链表的表头指针为空 */
void initList(Node **pNode)
{
    *pNode = NULL;
    printf("initList函数执行,初始化成功\n");
}
 
/* 2.创建线性表,此函数输入负数终止读取数据*/
Node *creatList(Node *pHead)
{
    Node *p1;
    Node *p2;
 
    p1=p2=(Node *)malloc(sizeof(Node)); //申请新节点
    if(p1 == NULL || p2 ==NULL)
    {
        printf("内存分配失败\n");
        exit(0);
    }
    memset(p1,0,sizeof(Node));
 
    scanf("%d",&p1->element);    //输入新节点
    p1->next = NULL;         //新节点的指针置为空
    while(p1->element > 0)        //输入的值大于0则继续,直到输入的值为负
    {
        if(pHead == NULL)       //空表,接入表头
        {
            pHead = p1;
        }
        else               
        {
            p2->next = p1;       //非空表,接入表尾
        }
        p2 = p1;
        p1=(Node *)malloc(sizeof(Node));    //再重申请一个节点
        if(p1 == NULL || p2 ==NULL)
        {
        printf("内存分配失败\n");
        exit(0);
        }
        memset(p1,0,sizeof(Node));
        scanf("%d",&p1->element);
        p1->next = NULL;
    }
    printf("creatList函数执行,链表创建成功\n");
    return pHead;           //返回链表的头指针
}
 
/* 3.打印链表,链表的遍历*/
void printList(Node *pHead)
{
    if(NULL == pHead)   //链表为空
    {
        printf("PrintList函数执行,链表为空\n");
    }
    else
    {
        while(NULL != pHead)
        {
            printf("%d ",pHead->element);
            pHead = pHead->next;
        }
        printf("\n");
    }
}
 
/* 4.清除线性表L中的所有元素,即释放单链表L中所有的结点,使之成为一个空表 */
void clearList(Node *pHead)
{
    Node *pNext;            //定义一个与pHead相邻节点
 
    if(pHead == NULL)
    {
        printf("clearList函数执行,链表为空\n");
        return;
    }
    while(pHead->next != NULL)
    {
        pNext = pHead->next;//保存下一结点的指针
        free(pHead);
        pHead = pNext;      //表头下移
    }
    printf("clearList函数执行,链表已经清除\n");
}
 
/* 5.返回单链表的长度 */
int sizeList(Node *pHead)
{
    int size = 0;
 
    while(pHead != NULL)
    {
        size++;         //遍历链表size大小比链表的实际长度小1
        pHead = pHead->next;
    }
    printf("sizeList函数执行,链表长度 %d \n",size);
    return size;    //链表的实际长度
}
 
/* 6.检查单链表是否为空,若为空则返回1,否则返回0 */
int isEmptyList(Node *pHead)
{
    if(pHead == NULL)
    {
        printf("isEmptyList函数执行,链表为空\n");
        return 1;
    }
    printf("isEmptyList函数执行,链表非空\n");
 
    return 0;
}
 
/* 7.返回单链表中第pos个结点中的元素,若pos超出范围,则停止程序运行 */
elemType getElement(Node *pHead, int pos)
{
    int i=0;
 
    if(pos < 1)
    {
        printf("getElement函数执行,pos值非法\n");
        return 0;
    }
    if(pHead == NULL)
    {
        printf("getElement函数执行,链表为空\n");
        return 0;
        //exit(1);
    }
    while(pHead !=NULL)
    {
        ++i;
        if(i == pos)
        {
            break;
        }
        pHead = pHead->next; //移到下一结点
    }
    if(i < pos)                  //链表长度不足则退出
    {
        printf("getElement函数执行,pos值超出链表长度\n");
        return 0;
    }
 
    return pHead->element;
}
 
/* 8.从单链表中查找具有给定值x的第一个元素,若查找成功则返回该结点data域的存储地址,否则返回NULL */
elemType *getElemAddr(Node *pHead, elemType x)
{
    if(NULL == pHead)
    {
        printf("getElemAddr函数执行,链表为空\n");
        return NULL;
    }
    if(x < 0)
    {
        printf("getElemAddr函数执行,给定值X不合法\n");
        return NULL;
    }
    while((pHead->element != x) && (NULL != pHead->next)) //判断是否到链表末尾,以及是否存在所要找的元素
    {
        pHead = pHead->next;
    }
    if((pHead->element != x) && (pHead != NULL))
    {
        printf("getElemAddr函数执行,在链表中未找到x值\n");
        return NULL;
    }
    if(pHead->element == x)
    {
        printf("getElemAddr函数执行,元素 %d 的地址为 0x%x\n",x,&(pHead->element));
    }
 
    return &(pHead->element);//返回元素的地址
}
 
/* 9.把单链表中第pos个结点的值修改为x的值,若修改成功返回1,否则返回0 */
int modifyElem(Node *pNode,int pos,elemType x)
{
    Node *pHead;
    pHead = pNode;
    int i = 0;
 
    if(NULL == pHead)
    {
        printf("modifyElem函数执行,链表为空\n");
    }
    if(pos < 1)
    {
        printf("modifyElem函数执行,pos值非法\n");
        return 0;
    }
    while(pHead !=NULL)
    {
        ++i;
        if(i == pos)
        {
            break;
        }
        pHead = pHead->next; //移到下一结点
    }
    if(i < pos)                  //链表长度不足则退出
    {
        printf("modifyElem函数执行,pos值超出链表长度\n");
        return 0;
    }
    pNode = pHead;
    pNode->element = x;
    printf("modifyElem函数执行\n");
     
    return 1;
}
 
/* 10.向单链表的表头插入一个元素 */
int insertHeadList(Node **pNode,elemType insertElem)
{
    Node *pInsert;
    pInsert = (Node *)malloc(sizeof(Node));
    memset(pInsert,0,sizeof(Node));
    pInsert->element = insertElem;
    pInsert->next = *pNode;
    *pNode = pInsert;
    printf("insertHeadList函数执行,向表头插入元素成功\n");
 
    return 1;
}
 
/* 11.向单链表的末尾添加一个元素 */
int insertLastList(Node **pNode,elemType insertElem)
{
    Node *pInsert;
    Node *pHead;
    Node *pTmp; //定义一个临时链表用来存放第一个节点
 
    pHead = *pNode;
    pTmp = pHead;
    pInsert = (Node *)malloc(sizeof(Node)); //申请一个新节点
    memset(pInsert,0,sizeof(Node));
    pInsert->element = insertElem;
 
    while(pHead->next != NULL)
    {
        pHead = pHead->next;
    }
    pHead->next = pInsert;   //将链表末尾节点的下一结点指向新添加的节点
    *pNode = pTmp;
    printf("insertLastList函数执行,向表尾插入元素成功\n");
 
    return 1;
}
 
/* 12.向单链表中第pos个结点位置插入元素为x的结点,若插入成功返回1,否则返回0 */
 
 
/* 13.向有序单链表中插入元素x结点,使得插入后仍然有序 */
/* 14.从单链表中删除表头结点,并把该结点的值返回,若删除失败则停止程序运行 */
/* 15.从单链表中删除表尾结点并返回它的值,若删除失败则停止程序运行 */
/* 16.从单链表中删除第pos个结点并返回它的值,若删除失败则停止程序运行 */
/* 17.从单链表中删除值为x的第一个结点,若删除成功则返回1,否则返回0 */
/* 18.交换2个元素的位置 */
/* 19.将线性表进行快速排序 */
 
/******************************************************************/
int main()
{
    Node *pList=NULL;
    int length = 0;
 
    elemType posElem;
 
    initList(&pList);       //链表初始化
    printList(pList);       //遍历链表,打印链表
 
    pList=creatList(pList); //创建链表
    printList(pList);
     
    sizeList(pList);        //链表的长度
    printList(pList);
 
    isEmptyList(pList);     //判断链表是否为空链表
     
    posElem = getElement(pList,3);  //获取第三个元素,如果元素不足3个,则返回0
    printf("getElement函数执行,位置 3 中的元素为 %d\n",posElem);   
    printList(pList);
 
    getElemAddr(pList,5);   //获得元素5的地址
 
    modifyElem(pList,4,1);  //将链表中位置4上的元素修改为1
    printList(pList);
 
    insertHeadList(&pList,5);   //表头插入元素12
    printList(pList);
 
    insertLastList(&pList,10);  //表尾插入元素10
    printList(pList);
 
    clearList(pList);       //清空链表
    system("pause");
     
}


  1. #include<stdio.h>  
  2. #include<malloc.h>  
  3.   
  4. typedef int Item;//定义数据项类型  
  5. typedef struct node * PNode;//定义节点指针  
  6. //节点的定义  
  7. typedef struct node  
  8. {  
  9.     Item item;//数据域  
  10.     PNode next;//链域  
  11.       
  12. }Node,* SList;  
  13.   
  14. /* 
  15. int SL_Creat(SList *p_list,int size) 
  16. 参数 
  17. p_list:指向一个链表指针,此处传入表头地址 
  18. size:要创建的链表分配的数据元素空间个数,不包含头节点 
  19. 返回值 
  20. 若成功返回1,否则返回0。 
  21. 功能 
  22. 该函数的功能是创建一个大小为size的链表并把链表的头指针赋给p_lsit所指的链表指针。 
  23.  
  24. */  
  25. int SL_Creat(SList *p_list,int size)  
  26. {  
  27.     PNode p=NULL;  
  28.     int i;  
  29.   
  30.     *p_list = (SList)malloc(sizeof(Node));  
  31.     if(*p_list==NULL)  
  32.         return -1;  
  33.     (*p_list)->next = NULL;  
  34.     for(i=size;i>0;i--)  
  35.     {  
  36.         p = (PNode)malloc(sizeof(Node));  
  37.         if(p==NULL)  
  38.             return -1;  
  39.         p->item = 0;  
  40.         p->next = (*p_list)->next;  
  41.         (*p_list)->next = p;  
  42.     }  
  43.     return 1;  
  44. }  
  45. /* 
  46. int SL_Insert(SList list,int pos,Item item) 
  47. 参数 
  48. list:要插入数据的单链表 
  49. int:指定要插入元素的位置,从1开始计数 
  50. item:要插入的数据项 
  51. 返回值 
  52. 若成功返回1,否则返回-1。 
  53. 功能 
  54. 该函数的功能是在链表list的pos位置插入新元素,其值为item。 
  55.  
  56. */  
  57. int SL_Insert(SList list,int pos,Item item)  
  58. {  
  59.     PNode p,q;  
  60.     int i;  
  61.   
  62.     p = list;  
  63.     i = 0;  
  64.     while(p!=NULL && i<pos-1)//将指针p移动到要插入元素位置之前  
  65.     {  
  66.         p = p->next;  
  67.         i++;//i记录p指向的是第几个位置  
  68.     }  
  69.     if(p==NULL || i > pos-1)  
  70.         return -1;  
  71.     q = (Node *)malloc(sizeof(Node));//未插入节点分配内存  
  72.     if(q!=NULL)//若内存分配成功,将节点插入指定位置  
  73.     {  
  74.         q->item = item;  
  75.         q->next = p->next;  
  76.         p->next = q;  
  77.         return 1;  
  78.     }  
  79.     else  
  80.     {  
  81.         return -1;  
  82.     }  
  83. }  
  84. /* 
  85. int SL_GetItem(SList list,int pos,Item *p_item) 
  86. 参数 
  87. list:要获取数据项所在的单链表 
  88. int:指定要获取元素在单链表中的位置 
  89. p_item:指向要接收数据项的变量 
  90. 返回值 
  91. 若成功返回1,否则返回-1。 
  92. 功能 
  93. 该函数的功能是获取在链表list的pos位置的元素的数据项,其值赋给p_item所指的变量。 
  94.  
  95. */  
  96. int SL_GetItem(SList list,int pos,Item *p_item)  
  97. {  
  98.     PNode p;  
  99.     int i;    
  100.   
  101.     p = list;  
  102.     i = 0;  
  103.     while(p!=NULL && i<pos)//将指针p移动到要返回的元素位置  
  104.     {  
  105.         p = p->next;  
  106.         i++;//i记录p指向的是第几个位置  
  107.     }  
  108.     if((p==NULL)||(i>pos))  
  109.     {  
  110.         return -1;  
  111.     }  
  112.     *p_item = p->item;  
  113.     return 1;  
  114. }  
  115. /* 
  116. int SL_Delete(SList list,int pos,Item * p_item) 
  117. 参数 
  118. list:要删除元素所在的单链表 
  119. int:指定要删除元素在单链表中的位置 
  120. p_item:指向接收删除元素的数据项的变量 
  121. 返回值 
  122. 若成功返回1,否则返回-1。 
  123. 功能 
  124. 该函数的功能是删除在链表list的pos位置的元素,其值赋给p_item所指的变量。 
  125.  
  126. */  
  127. int SL_Delete(SList list,int pos,Item * p_item)  
  128. {  
  129.     PNode p,q;  
  130.     int i;  
  131.     p = list;  
  132.     i = 0;  
  133.     while(p!=NULL && i<pos-1)//将指针p移动到要插入元素位置之前  
  134.     {  
  135.         p = p->next;  
  136.         i++;//i记录p指向的是第几个位置  
  137.     }  
  138.     if(p->next==NULL || i > pos-1)  
  139.         return -1;  
  140.     q = p->next;  
  141.     p->next = q->next;  
  142.     if(p_item != NULL)  
  143.         *p_item = q->item;  
  144.     free(q);  
  145.     return 1;  
  146. }  
  147. /* 
  148. int SL_SetItem(SList list,int pos,Item item) 
  149. 参数 
  150. list:要设置元素所在的单链表 
  151. int:指定要设置元素在单链表中的位置 
  152. p_item:要设置元素的数据项的值 
  153. 返回值 
  154. 若成功返回1,否则返回-1。 
  155. 功能 
  156. 该函数的功能是将链表list的pos位置的元素的数据项设置为item。 
  157.  
  158. */  
  159. int SL_SetItem(SList list,int pos,Item item)  
  160. {  
  161.     PNode p=NULL;  
  162.     int i;  
  163.     p = list;  
  164.     i = 0;  
  165.     while(p!=NULL && i<pos)//将指针p移动到要插入元素位置之前  
  166.     {  
  167.         p = p->next;  
  168.         i++;//i记录p指向的是第几个位置  
  169.     }  
  170.     if(p==NULL || i > pos)  
  171.         return -1;  
  172.     p->item = item;  
  173.     return 1;  
  174.   
  175. }  
  176. /* 
  177. int SL_Find(SList list,int *pos,Item item) 
  178. 参数 
  179. list:要查找元素所在的单链表 
  180. int:指向要存储的查得的元素的位置的变量 
  181. p_item:要查找元素的数据项的值 
  182. 返回值 
  183. 若成功返回1,否则返回-1。 
  184. 功能 
  185. 该函数的功能是在链表list中查找数据项为item的元素,将其位置值赋给pos所指的变量。 
  186.  
  187. */  
  188. int SL_Find(SList list,int *pos,Item item)  
  189. {  
  190.     PNode p;  
  191.     int i;  
  192.     p = list;  
  193.     i = 0;  
  194.     while(p!=NULL && p->item!=item)//将指针p移动到要插入元素位置之前  
  195.     {  
  196.         p = p->next;  
  197.         i++;//i记录p指向的是第几个位置  
  198.         if(p->item == item)  
  199.         {  
  200.             *pos = i; //返回查询到的位置  
  201.             return 1;  
  202.         }  
  203.     }  
  204.     return -1;    
  205. }  
  206. /* 
  207. int SL_Empty(SList list) 
  208. 参数 
  209. list:要判断的单链表 
  210. 返回值 
  211. 若为空则返回1,否则返回 0。 
  212. 功能 
  213. 该函数的功能是判断链表list是否为空表。 
  214.  
  215. */  
  216. int SL_Empty(SList list)  
  217. {  
  218.     PNode p;  
  219.     p = list;  
  220.     if(p->next == NULL)  
  221.         return 1;  
  222.     return 0;  
  223. }  
  224. /* 
  225. int SL_Size(SList list) 
  226. 参数 
  227. list:要查找的单链表 
  228. 返回值 
  229. 返回包含节点的个数。 
  230. 功能 
  231. 该函数的功能是返回链表list中节点的个数,包含头节点。 
  232.  
  233. */  
  234. int SL_Size(SList list)  
  235. {  
  236.     PNode p;  
  237.     int i;  
  238.   
  239.     p = list;  
  240.     i = 0;  
  241.     while(p!=NULL)  
  242.     {  
  243.         p = p->next;  
  244.         i++;  
  245.           
  246.     }  
  247.     return i;  
  248. }  
  249. /* 
  250. int SL_Clear(SList *p_list) 
  251. 参数 
  252. p_list:指向要清除的单链表 
  253. 返回值 
  254. 成功返回值为1。 
  255. 功能 
  256. 该函数的功能是清除链表的所有节点,包含头节点。 
  257.  
  258. */  
  259. int SL_Clear(SList *p_list)  
  260. {  
  261.     PNode p,q;  
  262.     int i;  
  263.   
  264.     p = *p_list;  
  265.     i = 0;  
  266.     while(p!=NULL)  
  267.     {  
  268.         q = p->next;//借助于q存储p的链域,否则释放p后无法引用  
  269.         free(p);  
  270.         p = q;  
  271.     }  
  272.     *p_list = NULL;//将所指的链表指针设为NULL  
  273.       
  274.     return 1;  
  275. }  


  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值