码迷,mamicode.com
首页 > 其他好文 > 详细

单链表总结篇

时间:2015-05-19 19:09:05      阅读:194      评论:0      收藏:0      [点我收藏+]

标签:单链表

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

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_t
typedef struct Node * node_ptr;//给struct Node*取个别名node_ptr

typedef 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_t
typedef struct Node * node_ptr;//给struct Node*取个别名node_ptr

typedef 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");

}

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

单链表总结篇

标签:单链表

原文地址:http://blog.csdn.net/xinyu913/article/details/45846833

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!