单链表总结篇

来源:互联网 发布:无间道1 知乎 编辑:程序博客网 时间:2024/05/16 01:02

【基本概念】单链表即单向链表,数据结构为一个接一个的结点组成,每个结点有两个成员,一个数据域一个指向下一个结点的指针,如下:

struct Node{    int data;    struct Node *next;};

单链表基本操作包括链表初始化、插入、删除,其中初始化操作是指让单链表存在一个头结点,其数据域随机,头结点指向下一个结点,每次访问都要从头结点开始访问,插入结点方式有两种,尾部插入和结点前部插入,尾部插入很简单与正常的输入顺序一致,而前部插入需要时常变动头结点的指针,始终让他指向新插入的,因为如果不调整头指针的话,在输出时是无法从头结点往前访问的,记住,它是单向链表。删除操作主要是定值查找删除,在链表里并不需要做什么删除操作,其实就是将前一结点指针指向目标节点的下一个结点位置,指针访问时直接跳跃,即可实现删除操作。


【测试代码】

#include<stdio.h>#include<stdlib.h>#include<stack>typedef int data_type;typedef struct Node node_t;// 给struct Node取个别名node_ttypedef struct Node * node_ptr;//给struct Node*取个别名node_ptrtypedef struct Node{    data_type data;    struct Node *node_next;//node_next是一个指向结构的指针,告诉指针要指向的地址就要付给它一个结构类型地址};//链表初始化node_t * init(){    node_ptr p;    p = (node_t *)malloc(sizeof(node_t));    p->node_next = NULL;    return p;}//在链表后面插入结点node_t *insert_back(node_ptr p , data_type data){    node_ptr pnew = (node_t *)malloc(sizeof(node_t));    pnew ->node_next = NULL;    pnew ->data = data;    p->node_next = pnew;    return pnew;}void remove(node_ptr p, data_type data){    node_ptr find = p;    if(!find)        return ;    while(find->node_next->data !=data)    {        find= find->node_next;    }    find->node_next = find->node_next->node_next ;}//正常打印void print(node_ptr p){    if(!p)    {            printf("no data, you think too much");            return ;    }    while(p->node_next != NULL)    {        printf("%d ", p->data);        p = p->node_next;    }    printf("%d ", p->data);    printf("\n");}void main(){    node_ptr pnode, list;    pnode = init();    list = pnode;    pnode = insert_back(pnode, 1);    pnode = insert_back(pnode, 2);    pnode = insert_back(pnode, 3);    pnode = insert_back(pnode, 4);    pnode = insert_back(pnode, 5);    pnode = insert_back(pnode, 6);    printf("normal print:");    print(list->node_next);    printf("-------------------------------------------\n");    remove(list,1);    printf("remove one node 1 print:");    print(list->node_next);    printf("-------------------------------------------\n");    remove(list,2);    remove(list,3);    remove(list,4);    remove(list,5);    remove(list,6);    printf("remove all print:");    print(list->node_next);    printf("\n-------------------------------------------\n");}

【输出】
这里写图片描述
这段测试代码中使用的是尾部插入,设置了一个指针pnode指向尾结点,指针list始终指向头结点,访问链表时从list开始,而pnode就用于插入新结点和删除结点,插入的新节点永远在尾部后面,这样要比**list形式理解起来简单一点,大部分的资料都喜欢用双重指针,但是双重指针繁杂不易理解,尤其在访问地址变换的时候,很容易出错,所以先以这种简单的方式来理解单链表的基本思想。
结点存储方式如下
这里写图片描述
以前部插入为例,设计测试代码如下:

#include<stdio.h>#include<stdlib.h>#include<stack>typedef int data_type;typedef struct Node node_t;// 给struct Node取个别名node_ttypedef struct Node * node_ptr;//给struct Node*取个别名node_ptrtypedef struct Node{    data_type data;    struct Node *node_next;//node_next是一个指向结构的指针,告诉指针要指向的地址就要付给它一个结构类型地址};node_t * init(){    node_ptr p;    p = (node_t *)malloc(sizeof(node_t));    p->node_next = NULL;    return p;}//链表从前面插入node_t * insert_front(node_ptr p , data_type data){    p->data = data;    node_ptr pnew = (node_t *)malloc(sizeof(node_t));    pnew->node_next = p;    return pnew;}void remove(node_ptr p, data_type data){    node_ptr find = p;    if(!find)        return ;    while(find->node_next->data !=data)    {        find= find->node_next;    }    find->node_next = find->node_next->node_next ;}//正常打印void print(node_ptr p){    if(!p)    {            printf("no data, you think too much");            return ;    }    while(p->node_next != NULL)    {        printf("%d ", p->data);        p = p->node_next;    }    printf("%d ", p->data);    printf("\n");}void main(){    node_ptr pnode, list;    pnode = init();    pnode = insert_front(pnode, 1);    pnode = insert_front(pnode, 2);    pnode = insert_front(pnode, 3);    pnode = insert_front(pnode, 4);    pnode = insert_front(pnode, 5);    pnode = insert_front(pnode, 6);    list = pnode;    printf("normal print:");    print(list);    printf("-------------------------------------------\n");    remove(list,1);    printf("remove one node 1 print:");    print(list->node_next);    printf("-------------------------------------------\n");    remove(list,2);    remove(list,3);    remove(list,4);    remove(list,5);    remove(list,6);    printf("remove all print:");    print(list->node_next);    printf("\n-------------------------------------------\n");}

【输出】
这里写图片描述
注意两个测试代码输出有什么区别,前向插入,是倒着输出的,跟输入顺序不一样。
其他单链表相关操作都是在此基础上做的,忘记了单链表怎么操作时可以参考的

0 0
原创粉丝点击