单链表

调bug真是够了....

#ifndef LINKLIST_H
#define LINKLIST_H

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
//定义宏变量

#define TRUE 1
#define FALSE 0
#define OVERFLOW -1
#define OK 1

//设置一个数据类型
typedef int elemType;

//链表结构体
typedef struct LNode
{
    elemType Data;
    struct LNode *next;
} LNode;

//如下为所有链表的函数声明

//初始化
LNode *CreatLinkList(void);

void InitLinkList(LNode *List);

//销毁链表
LNode *DestroyLinkList(LNode *List);

void FinitLinkList(LNode *List);

void ClearLinkList(LNode *List);

//链表判空
bool IsEmptyList(LNode *List);

//查找元素
//LNode *FindDataNode(LNode *List,elemType data,int *position);

LNode *FindPosNode(LNode *List, int position);

elemType GetListElem(LNode *List, int position);

//插入
LNode *AddNode(LNode *List, LNode *prevNode, elemType data);

LNode *InsertList(LNode *List, int position,elemType data);

//表长查询
int GetLinkListLength(LNode *List);

//删除元素
elemType DeleteLinkListElem(LNode *List,int position);

//修改某个元素
void ChangeLinkListElem(LNode *List,int position, elemType data);

//遍历显示链表数据
void ShowLinkList(LNode *List);

#endif // LINKLIST_H

/*
name: LNode* CreatLinkList(void)
return:
	List: 表示初始化成功,返回创建好的单链表指针
	OVERFLOW:表示初始化失败,内存未开成功
parm:
	List : 指向一个链表指针,此处传入表头地址
desc:
	创建并初始化链表

*/
LNode *CreatLinkList(void)
{
    LNode *List = NULL;
    if(NULL == (List = (LNode *)malloc(sizeof(LNode))))//开辟单链表头结点
    {
        //开辟失败
        printf("Init memory overflow\n");
        exit(EXIT_FAILURE);
    }

    //初始化链表
    InitLinkList(List);

    return List;
}

/*
name:void InitLinkList(LNode *List)
return:
	无
parm:
	List:指向一个链表指针,此处传入表头地址
desc:
	初始化链表

*/
void InitLinkList(LNode *List)
{
    List->Data = 0;//第一个都节点数据域中存储的是表中元素个数,初始化为0个
    List->next = NULL;//表头指向空
}

/*
name:LNode *DestroyLinkList(LNode *List);
return:
	无
parm:
	List:指向一个链表指针,此处传入表头地址
desc:
	销毁创建的单链表,执行以下操作:
	1,清空单链表;2,释放头结点

*/
LNode *DestroyLinkList(LNode *List)
{
    ClearLinkList(List);      //清空单链表
    FinitLinkList(List);      //释放头指针
    List = NULL;
    return List;
}

/*
name:void FinitLinkList(LinkList *List)
return:
	无
parm:
	List:指向一个链表指针,此处传入表头地址
desc:
	释放头结点

*/
void FinitLinkList(LNode *List)
{
    assert(List->next == NULL); //对空链表后处理指针

    if(NULL != List) // 如果List指向的不是空
    {
        free(List);
    }
}


/*
name:LNode* DestroyLinkList(LNode *List);
return:
	无
parm:
	List:指向一个链表指针,此处传入表头地址
	0:表示第0个元素
desc:
	清空单链表

*/
void ClearLinkList(LNode *List)
{
    while(NULL != List->next) //如果List指向不为空,即链表不为空
    {
        DeleteLinkListElem(List,0); //删除第一个元素
    }

}


/*
name:int IsEmptyList(LNode *List);
return:
	ture: 是空表
	false:不是空表
parm:
	List:指向一个链表指针,此处传入表头地址
	0:表示第0个元素
desc:
	判断链表是不是为空

*/
bool IsEmptyList(LNode *List)
{
    return(List->Data == 0);//如果元素为0个则返回true,否则返回false
}
/*
name:LNode *FindPosNode(LNode *List, int position);
return:
	成功 返回指向待查找结点的指针
	失败 返回NULL
parm:
	List:指向一个链表指针,此处传入表头地址
	position:待查找的链表指针的位置
desc:
	查找到链表中第position个结点

*/
LNode *FindPosNode(LNode *List, int position)
{
    assert(List != NULL);//链表不为空
    assert(position >= -1 && position < List->Data + 1); //插入的位置必须在范围内

    LNode *pNode = List;
    int pos = -1;

    while(pNode != NULL && pos < position) //遍历链表,找到第position个结点
    {
        pNode = pNode->next;
        pos++;
    }

    if(pNode == NULL || pos < position)  //查找失败
    {
        return NULL;
    }
    else
    {
        return pNode; //成功
    }
}


/*
name:LNode *FindDataNode(LNode *List,elemType data,int *position);
return:
	成功 返回节点node在链表中的位置
	若失败 返回 -1**********************************************************************************************
parm:
	List:指向一个链表指针,此处传入表头地址
	data: 待查找节点的数据信息
desc:
	查找data元素,并且返回节点node在链表中的位置

*/
/*LNode *FindDataNode(LNode *List,elemType data,int *position)
{
    LNode *node = List->next;  //指针node指向头结点的下一个元素,即链表的第一个元素

    int pos = 0;  //用来记录位置

    while(NULL != node && node->Data != data) //如果node不为空,并且node的数据域不等于data
    {
        node = node->next;  //那就移到下一个元素
        pos++;              //pos也加1
    }

    *position = pos;    //讲出现的位置传递回去

    return node;        //返回节点的信息***************************************************************************************
}
*/
/*
name:elemType GetListElem(LNode *List, int position);
return:
	第position个元素的值
parm:
	List:指向一个链表指针,此处传入表头地址
	0:表示第0个元素
desc:
	返回链表中第position个元素的值

*/
elemType GetListElem(LNode *List, int position)
{
    LNode *pNode = FindPosNode(List,position);  //找到该链表的第position个元素

    return pNode->Data;  //返回该元素的数据域
}

/*
name:LNode *AddNode(LNode *List, LNode *prevNode, elemType data);
return:
	新结点
parm:
	List:指向一个链表指针,此处传入表头地址
	prevNode: 待插入位置的前一个结点
	data:待插入结点的数据
desc:
	将数据data插入链表prevNode结点的下一个位置上

*/
LNode *AddNode(LNode *List, LNode *prevNode, elemType data)
{
    assert(NULL != prevNode); //插入结点不能为空

    LNode *newNode = NULL; //创建新结点

    if(NULL ==(newNode = (LNode *)malloc(sizeof(LNode)))) //为新结点开空间
    {
        printf("Error,not enough memeory\n"); //开辟空间失败
    }

    newNode->Data = data; //将data赋予新结点的数据域
    newNode->next = NULL;  //新节点指向空

    newNode->next = prevNode->next; //新节点的后继为prevNode结点的后继
    prevNode->next = newNode;       //更新新结点为prevNode结点的后继

    List->Data++;                   //表头数据域记录元素个数加一

    return newNode;                 //返回新节点
}
/*
name:LNode *InsertList(LNode *List, int position,elemType data);
return:
	插入成功 : 返回新结点
	插入失败 : 返回0
parm:
	List:指向一个链表指针,此处传入表头地址
	position: 要插入的位置
	data:要插入元素的值
desc:
	将值为data的结点插入到第position个位置

*/
LNode *InsertList(LNode *List, int position,elemType data)
{
    assert(NULL != List);  //判断头结点不为空

    assert(position >= 0 && position < List->Data + 1);  //要插入的位置没有超出链表现在的元素个数

    LNode *prevNode = FindPosNode(List, position - 1); //先找到要插入位置结点的前一个结点
    LNode *newNode = NULL;                //令新结点为空

    if(NULL == (newNode = AddNode(List, prevNode, data))) //将新结点插入到待插位置
    {
        //插入成功
        return newNode;
    }
    else
    {
        //插入失败
        return NULL;
    }
}

/*
name:int GetLinkListLength(LNode *List);
return:
	表中有几个元素
parm:
	List:指向一个链表指针,此处传入表头地址
desc:
	表中有几个元素

*/
int GetLinkListLength(LNode *List)
{
    return List->Data;  //返回表头的数据域,也就是表长
}

/*
name:elemType DeleteLinkListElem(LNode *List,int position);
return:
	返回待删除结点的数据域
parm:
	List:指向一个链表指针,此处传入表头地址
	position: 表示要删除结点的位置
desc:
	删除表中第position个元素

*/

elemType DeleteLinkListElem(LNode *List,int position)
{
    assert(NULL != List);   //表头不为空
    assert(position >= 0 && position < List->Data); //position没有超出链表的界限

    LNode *prevNode = FindPosNode(List,position - 1); //prevNode为position的前驱

    LNode *delNode = prevNode->next; //delNode指针指向要删除的结点
    elemType delElem = delNode->Data; //delmElem 存要删除结点的数据
    prevNode->next = delNode->next;   //利用delNode实现待删除结点的前驱和后继相连,从而删除待删结点
    free(delNode);//清空被删除的结点的空间

    List->Data--;//链表元素减一

    return delElem;//返回被删除的结点
}

/*
name:void ChangeLinkListElem(LNode *List,int position,elemType data);
return:
	无
parm:
	List:指向一个链表指针,此处传入表头地址
	position: 表示要修改结点的位置
desc:
	修改表中第position个元素

*/
void ChangeLinkListElem(LNode *List,int position,elemType data)
{
    LNode *pNode = FindPosNode(List, position); //找到要修改的结点

    pNode->Data = data;  //修改数据域
}
/*
name:void ShowLinkList(LNode *List);
return:
	无
parm:
	List:指向一个链表指针,此处传入表头地址
desc:
	显示单链表的信息

*/
void ShowLinkList(LNode *List)
{
    if(NULL == List)   //单链表可能没有初始化
    {
        printf("Not Init\n");  //打印错误
        return ;
    }

    if(List->Data == 0)    //如果链表中没有元素,则退出
    {
        return ;
    }

    LNode *pNode = List->next;  //从第一个元素开始

    while(NULL != pNode)
    {
        printf("%d ", pNode->Data);  //打印数据

        pNode = pNode->next;    //指向下一个元素
    }

    printf("\n");

}

#define LIST_SIZE 7
//如下为验证过程

int main()
{
    int pos;

    printf("TEST1\n");        //实验一
    LNode *L = CreatLinkList();   //创建链表

    for(pos = 0; pos < LIST_SIZE; pos++) //插入元素
    {
        InsertList(L,pos,pos+1);
    }
    ShowLinkList(L); //遍历
    for(pos = 0; pos < LIST_SIZE; pos++)  //另一种方式遍历
    {
        printf("%d ",GetListElem(L,pos));
    }
    printf("\n");

    DeleteLinkListElem(L,0);  //删除第0个元素
    ShowLinkList(L);           //遍历
    DeleteLinkListElem(L,1);    //删除第1个元素
    ShowLinkList(L);            //遍历

    ClearLinkList(L);           //清空单链表
    ShowLinkList(L);            //遍历
    DestroyLinkList(L);           //销毁链表


    printf("\n\nTEST2\n");    //实验二
    LNode List;
    InitLinkList(&List);
    for(pos = 0; pos < LIST_SIZE; pos++) //循环向单链表中插入数据
    {
        InsertList(&List, pos, pos + 1);
    }
    ShowLinkList(&List);                  //显示
    ClearLinkList(&List);                   //清空
    ShowLinkList(&List);                    //显示

    printf("\n\nTEST3\n");                  //实验三
    LNode *prevNode = &List;                //设置指针表示前置结点
    LNode *addNode = NULL;                  //待添加指针
    for(pos = 0; pos < LIST_SIZE; pos++)
    {
        if(NULL !=(addNode = AddNode(&List, prevNode, pos + 1))) //向前置结点后面加入元素
        {
            prevNode = addNode;
        }
    }
    ShowLinkList(&List);                     //显示
    ClearLinkList(&List);



    return EXIT_SUCCESS;     //退出

}



 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值