首页 > 技术文章 > C/C++单向链表

chaeyeon 2016-10-06 22:40 原文

由于时间仓促,作者并没有进行任何的检查,总之徒手165行,调试无BUG,基本功能的实现并无大问题,可能有些细节考虑不周(这也是C/C++的诟病,小车不倒只管前推),还忘见谅。

代码是在C++环境编写,可以在C编译平台运行,但要进行修改(把声明变量语句,写在执行语句之前)。

 

#include <stdio.h>
#include <stdlib.h>
//定义节点,所有节点必须用malloc()申请在堆中,在程序执行阶段保证空间的存在;
//-1表示非正常退出
typedef struct node
{
    int data;
    node *next;
} Node;
//用来表示链表的长度,-1表示无头节点的空表
int len = -1;
//定义一个全局头结点
Node *head = NULL;

//创建一个带有头节点的空链表
void createNodeList()
{
    if (head != NULL)//表示为非空表
        exit(-1);//非正常退出
    head = (Node *)malloc(sizeof(Node));//申请堆空间
    if (head == NULL) //如果head==NULL则申请失败
        exit(-1);
    //头结点的数据域为0,指针域为NULL
    head->data = 0;
    head->next = NULL;
    len = 0;//0表示有头节点的空表

}

//添加一个节点(向当前节点的指针域为NULL的节点后面添加)
void addNode(int data)
{
    if (head == NULL)//表示为空表
        exit(-1);
    Node *newNode = (Node *)malloc((sizeof(Node)));//创建一个新节点
    if (newNode == NULL)//申请失败
        exit(-1);
    //初始化新结点的数据域和指针域
    newNode->data = data;
    newNode->next = NULL;
    //连接工作
    Node *p = head;//当前节点
    Node *q = head->next;//下一个节点
    while (q != NULL)
    {
        //循环成立表示当前结点的指针域不为NULL
        p = q;//更新当前结点
        q = p->next;//更新当前结点的
    }
    //循环结束表示当前节点的指针域为NULL
    //更新当前节点指针域为新结点
    p->next = newNode;
    len++;//表长加一
}
//获取节点数据(0<index<len)
int getNode(int index)
{
    int data = -1;
    if (head == NULL)//表示为空表
        exit(-1);
    if (index < 0)//下标要从0开始
        exit(-1);
    if (index >= len)//下标越界
        exit(-1);
    Node *p = head->next;
    data = p->data;
    for (int i = 0; i < index;i++)
    {
        p=p->next;
    }
    data = p->data;
    return data;
}
//元素查找
int getData(int data)
{
    if (head == NULL)//表示为空表
        exit(-1);
    Node *p = head->next;//表示第一个节点
    for (int i = 0;p!=NULL;i++)
    {
        if (p->data==data)
            return i;//返回下标
        p = p->next;
    }
}
//向屏幕打印链表
void getLinks()
{
    if (head == NULL)//表示为空表
        exit(-1);
    //指向第一个节点
    Node *p = head->next;
    //如果该结节不为NULL则表示存在该节点
    while (p != NULL)
    {
        printf("%d\n", p->data);
        p = p->next;
    }
}
//删除节点
void removeNode(int index)
{
    if (head == NULL)//表示为空表
        exit(-1);
    if (index < 0)//下标要从0开始
        exit(-1);
    if (index >= len)//下标越界
        exit(-1);
    //p表示当前节点,q表示当前节点的指针域
    Node *p = head;//要被删除的前一个节点
    Node *q = head->next;//要被删除的节点
    for (int i = 0; i < index;i++)
    {
        p = q;
        q = p->next;
    }
    //重新连接
    p->next = q->next;
    free(q);//删除q节点
    len--;//表长减一
}
//清空链表
void cleanLinks()//表示为空表
{
    if (head == NULL)
        exit(-1);

    Node *p = head;//当前节点
    Node *q=head->next;//下一个节点
    free(p);//删除当前节点
    while (q!=NULL)
    {
        p = q;
        q = p->next;
        free(p);//删除当前节点
    }
    len = -1;//表示该表为空
}
void main()
{
    //创建表
    createNodeList();
    //添加元素
    addNode(1);
    addNode(2);
    addNode(3);
    addNode(4);
    //打印表,和表长
    getLinks();
    printf("len:%d\n", len);
    //查看第三个节点"4"
    printf("index 3:%d\n",getNode(3));
    //数据4所在节点下标
    printf("data 4:%d\n",getData(4));
    //删除第三个元素”3“
    removeNode(2);
    //分隔符
    printf("=============\n");
    //再次打印表和表长
    getLinks();
    printf("len:%d\n", len);
    cleanLinks();
    system("pause");
}

 

推荐阅读