单向链表的基本操作

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单向链表的基本操作相关的知识,希望对你有一定的参考价值。

更新时间:

2017.10.20  创建链表,遍历链表,插入节点,删除节点,原地逆序,求最大值,求节点个数,求平均值,摧毁链表

1.单链表的结构

struct NODE
{
    int m_data;
    struct NODE *next;
};

typedef struct NODE node;

 

2.后插法创建具有n个节点的单链表(带头结点)

node *link_list_create(unsigned int n)
{
    node *head = NULL;
    node *tail_node = NULL;
    node *new_node = NULL;
    int i = 0;

    head = (node *)malloc(sizeof(node));
    if (head == NULL)
    {
        return NULL;
    }
    head->m_data = 0;

    tail_node = head;

    for (i=0; i<n;i++)
    {
        new_node = (node *)malloc(sizeof(node));
        if(new_node == NULL)
        {
            return NULL;
        }
        printf("please input the data of node %d :",i+1);
        scanf("%d",&new_node->m_data);

        new_node->next = NULL;
        tail_node->next = new_node;
        tail_node = new_node;
    }
    return head;
}

3.遍历链表

void link_list_traverse(const node *head)
{
    if (head == NULL)
    {
        return;
    }

    node *ptr = head->next;
    while (ptr!=NULL)
    {
        printf("%d ", ptr->m_data);
        ptr = ptr->next;
    }
}

4.插入节点

void node_insert(node *head, unsigned int pos, int data)
{

    node *new_node = NULL;
    node *ptr = head;
    int i = 0;

    while ((ptr!=NULL)&&(i<pos-1))
    {
        i++;
        ptr = ptr->next;
    }

    if ((ptr==NULL)||(i>pos-1))
    {
        return;
    }

    new_node = (node *)malloc(sizeof(node));
    if (new_node ==NULL)
    {
        return;
    }
    new_node->m_data = data;
    new_node->next = ptr->next;
    ptr->next = new_node;
}

5.删除节点

void node_delete(node *head, unsigned int pos)
{
    node *ptr = head;
    node *tmp = NULL;
    int i = 0;

    while ((ptr->next!=0)&&(i<pos-1))
    {
        i++;
        ptr = ptr->next;
    }

    if ((ptr->next == NULL)||(i>pos-1))
    {
        return;
    }

    tmp = ptr->next;
    ptr->next = tmp->next;
    free(tmp);
}

6.链表原地逆序

void link_list_reverse(node *head)
{
    node *cur = NULL;
    node *last = NULL;
    node *next = NULL;
    if (head == NULL)
    {
        return;
    }

    cur = head->next;
    while (cur != NULL)
    {
        next = cur->next;
        cur->next = last;
        last = cur;
        cur = next;
    }
    head->next = last;
}

7.获取最大值

迭代:

int get_max(const node *head)
{
    int max = 0;
    node *tmp = NULL;
    if (head == NULL)
    {
        return -1;
    }

    tmp = head->next;
    max = tmp->m_data;
    while (tmp != NULL)
    {
        max = tmp->m_data >= max ? tmp->m_data : max;
        tmp = tmp->next;
    }
    return max;
}

递归:

int get_max2(const node *head)
{
    int max = 0;
    if (head == NULL)
    {
        return -1;
    }

    else if (head->next == NULL)
    {
        return head->m_data;
    }

    else
    {
        max = get_max(head->next);
        max = head->m_data >= max ? head->m_data : max;
        return max;
    }
}

8.求节点个数(头结点不计入)

迭代:

int node_count(const node *head)
{
    int count = 0;
    node *tmp = NULL;
    if (head == NULL)
    {
        return -1;
    }
    tmp = head->next;
    for (count = 0; tmp != NULL; count++)
    {
        tmp = tmp->next;
    }

    return count;
}

递归:

int node_count2(const node *head)
{
    int count = 0;
    if (head == NULL)
    {
        return -1;
    }
    
    else if (head->next == NULL)
    {
        return 0;
    }

    else
    {
        count = 1;
        count += node_count(head->next);
        return count;
    }
}

9.求平均值

迭代:

float link_average(const node *head,int count)
{
    node *tmp = NULL;
    float cur_ave = 0.0;
    if (head == NULL)
    {
        return -1.0;
    }
    tmp = head->next;
    cur_ave = (float)tmp->m_data/count;

    while (tmp != NULL)
    {
        cur_ave += (float)(tmp->m_data)/count;
        tmp = tmp->next;
    }
    return cur_ave;
}

递归:

float link_average2(node *head, int count)
{
    float cur_ave = 0.0;
    if (head == NULL)
    {
        return -1.0;
    }
    
    else if (head->next == NULL)
    {
        return 0.0;
    }

    else
    {
        cur_ave = (float)head->next->m_data/count;
        cur_ave += link_average(head->next,count);
        return cur_ave;
    }
}

10.摧毁链表

void link_list_destroy(node *head)
{
    node *ptr = NULL;
    while (head!=NULL)
    {
        ptr = head;
        head = head->next;
        printf("free node:%d ",ptr->m_data);
        free(ptr);
    }

}

  

 

以上是关于单向链表的基本操作的主要内容,如果未能解决你的问题,请参考以下文章

链表的java实现(单向双向链表,单向链表的反转)

JavaScript单向链表的创建遍历插入删除操作

JavaScript数据结构与算法 单向链表

简单的单向链表的java实现

线性表之单向链表的基本操作实现

[原创]用C++类实现单向链表的增删查和反转操作