数据结构之单链表

单向链表,大致操作有插入,删除,遍历,查找,销毁,它存取方便,只要修改节点的指针域即可。只是查找时,每次都需要从第一个开始遍历查找。

第一个节点只有直接后继,最后一个节点只有直接前驱。

对于插入操作,有头插法,尾插法,任意插,这些我们在实际运用中都要考虑到。它的一优势就是节省空间,灵活。而顺序表就容易造成空间的浪费。插入删除操作还会造成大量数据的移动。

单链表其实我认为是一种更为实用的数据类型,它将各种类型封装起来,来解决生活工作中遇到的实际问题。

下面开始实战:

/* list.h 头文件的定义 */

#ifndef _LIST_H_
#define _LIST_H_
#include <assert.h>
typedef struct node
{
    int data;
    struct node *next;
}node_t;
node_t *list_insert_fornt(node_t *head,int data);

typedef  void (*FUNC)(node_t *);
void list_for_each(node_t *head,FUNC f);

node_t *list_get_node(node_t *head,int index);
node_t *list_insert_at(node_t *head,int data,int index);

node_t *list_remove_at(node_t *head,int index);

node_t *list_find(node_t *head,int data,int *ret);

node_t *list_free(node_t *head,int data);
#endif  /* _LIST_H_ */



/* list.c    接口的实现 */

#include "list.h"
#include <stdio.h>
node_t *list_insert_fornt(node_t *head,int data)
{
    node_t *n = (node_t *)malloc(sizeof(node_t));
    assert(n != NULL);
    n->data  = data;
    n->next = NULL;
    if(head == NULL)
        head = n;
    else
    {
        n->next = head;
        head = n;
    }
    return head;
}
void  *list_for_each(node_t *head,FUNC f)
{
    while(head)
    {
        f(head);
        head = head->next;
    }
}
node_t *list_get_node(node_t *head,int index)
{
    int j = 0;
    while(head && j < index)
    {
        head = head->next;
        j++;
    }
    if(j == index)
<span style="white-space:pre">	</span>return head;
    return NULL;   //return head;
}
node_t *list_insert_at(node_t *head,int data,int index)
{
    if(index == 0)
    return list_insert_front(head,data);
    node_t *n = (node_t *)malloc(sizeof(node_t));
    assert(n != NULL);
    n->data = data;
    n->next = NULL;
    node_t *p = NULL;
    p = list_get_node(head,index - 1);
    if(p != NULL)
    {
        n->next = p-next;
        p->next = n;
    }
    else
        printf("insert error.\n");
    return head;
}
node_t *list_remove_at(node_t *head,int index)
{
    assert(index >= 0);
    if(index == 0)
    {
        n = head;
        free(n); 
        head = head->next;
    }
    node_t *p = NULL;
    p = list_get_node(head,index -1);
    if(p == NULL || p->next == NULL)
    {
        fprintf(stderr,"remove error.\n");
        exit(EXIT_FAILURE);
    }
    n = p->next;
    p->next = n->next;
    return head;
}
node_t *list_find(node_t *head,int data,int *ret)
{
    *ret = -1;
    int i = 0;
    while(head)
    {
        if(data == head->data)
        {
            *ret = i;
            break;
        }
        head = head->next;
        i++;
    }
    return head;
}
node_t *list_free(head,data)
{
    node_t *tmp = head;
    while(head)
    {
        head =head->next;
        free(tmp);
        tmp = head;
    }
    return head;
}



/* main.c  测试代码  */


#include "list.h"
#include <stdio.h>
void print_node(node_t *n)
{
    printf("data = %d \n",n->data);
}
int main(void)
{
    node_t *head = NULL;
    head = list_insert_fornt(head,30);
    head = list_inset_fornt(head,20);
    head = list_insert_fornt(head,10);
    list_for_each(head,print_node);
    putchar('\n');
    node_t *n = NULL;
    n = list_get_node(head,1);
    if(n != NULL)
        printf("data = %d\n",n->data);
    else
        printf("not find node.\n");
    head = list_insert_at(head,15,1);
    list_for_each(head,print_node);
    putchar('\n');

    head = list_remove_at(head,2);
    list_for_each(head,print_node);
    putchar('\n');

    node_t *n = NULL;
    int ret = 0;
    n = list_find(head,20,&ret);
    if(n != NULL)
        printf("data = %d index = %d \n",n->data,ret);
    else
        printf("not find.\n");
    head =list_free(head,data);
    assert(head == NULL);
    return 0;
}


以下是运行示例:分别是插入,查找,任意插入,删除节点,找出节点,最后销毁链表。



(finish)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值