嵌入式学习之路(二十二)——数据结构(4)

嵌入式学习之路(二十二)——数据结构(4)

一。数据结构的实现----单向链表

今天我们来写一下单向链表的程序,在面试笔试中可能比较喜欢考链表

/*************************************************
**
** 文件名称:nl_test.c
** 文件功能:单向链表的各种功能实现
** 文件作者:紫瞳标
** 文件时间:2014-1-8
** 功能简介:1.正向打印
**           2.反向打印
**           3.逆转链表
**           4.遍历一次,找出链表的中间值,偶数时取左边的
**
*************************************************/
#include "node_list.h"
int main()
{
    LIST list;
    list_init(&list);/*初始化链表*/
    list_append(&list,23);/*追加23*/
    list_append(&list,33);/*追加33*/
    list_append(&list,43);/*追加43*/
    list_append(&list,53);/*追加53*/
    printf("该链表有%d个元素\n",list_size(&list));
    printf("正向打印结果为\n");
    list_print(&list);/*正向打印*/
    printf("反向打印结果为\n");
    list_rprint(&list);/*反向打印*/
    
    list_reverse(&list);/*逆转链表*/
    printf("逆转后正向打印\n");
    list_print(&list);
    printf("中间值是%d\n",list_middle(&list));/*取中间值*/
    list_deinit(&list);
    return 0;
}

/*************************************************
**
** 文件名称:node_list.c
** 文件功能:单向链表的各种操作
** 文件作者:紫瞳标
** 文件时间:2014-1-8
**
*************************************************/
#include <stdlib.h>
#include "node_list.h"
/*************************************************
**
** 函数名称:creat_node()
** 函数功能:创建新的节点
** 函数形参:新建存入的数据
** 返回值  :节点结构体指针
**
*************************************************/
NODE_LIST * create_node(int data)
{
    NODE_LIST * node = malloc(sizeof(NODE_LIST));
    node->data = data;
    node->next = NULL;
    return node;
}
/*************************************************
**
** 函数名称:destroy_node()
** 函数功能:销毁节点
** 函数形参:删除的结构体指针
** 返回值  :节点结构体指针
**
*************************************************/
NODE_LIST * destroy_node(NODE_LIST* node)
{
    NODE_LIST *temp = node->next;
    free(node);
    return temp;
}
/*************************************************
**
** 函数名称:list_init()
** 函数功能:链表的初始化
** 函数形参:链表的结构体指针
** 返回值  :无
**
*************************************************/
void list_init(LIST *list)
{
    list->head = NULL;
    list->tail = NULL;
}
/*************************************************
**
** 函数名称:list_deinit()
** 函数功能:释放剩余的节点,回到初始状态
** 函数形参:链表的结构体指针
** 返回值  :无
**
*************************************************/
void list_deinit(LIST *list)
{
    while(list->head)
    {
        list->head = destroy_node(list->head);
    }
    list->tail = NULL;
}
/*************************************************
**
** 函数名称:list_append()
** 函数功能:追加节点数据
** 函数形参:链表的结构体指针,追加的数据
** 返回值  :无
**
*************************************************/
void list_append(LIST* list ,int data)
{
    NODE_LIST *node = create_node(data);
    /*尾节点存在,直接放在尾节点后面*/
    if(list->tail)
    {
        list->tail->next = node;
    }
    /*空的链表*/
    else
        list->head = node;
    /*无论是否是空的链表,都将这个节点变成尾节点,实现追加*/
    list->tail = node;
}
/*************************************************
**
** 函数名称:list_size()
** 函数功能:统计链表中的个数
** 函数形参:链表的结构体指针
** 返回值  :链表中的个数
**
*************************************************/
size_t list_size(LIST* list)
{
    int size = 0;
    NODE_LIST *node = NULL;/*用一个结点遍历*/
    /*不能随便改变list的内容*/
    for(node = list->head;node;node = node->next)
    {
        ++size;
    }
    return size;
}
/*************************************************
**
** 函数名称:list_print()
** 函数功能:正向打印
** 函数形参:链表的结构体指针
** 返回值  :无
**
*************************************************/
void list_print(LIST* list)
{
    NODE_LIST *node = NULL;
    for(node = list->head;node;node = node->next)
    {
        printf("%d ",node->data);
    }
    printf("\n");
}
/*************************************************
**
** 函数名称:rprint()
** 函数功能:反向打印节点的递归函数,实现反向打印
** 函数形参:链表的结构体指针
** 返回值  :无
**
*************************************************/
static void rprint(NODE_LIST *head)
{
    if(head)
    {
        rprint(head->next);
        printf("%d ",head->data);
    }
}
/*************************************************
**
** 函数名称:list_rprint()
** 函数功能:反向打印链表
** 函数形参:链表的结构体指针
** 返回值  :无
**
*************************************************/
void list_rprint(LIST* list)
{
    rprint(list->head);
    printf("\n");
}
/*逆转以参数head的目标节点为首的子链表*/
/*************************************************
**
** 函数名称:reverse()
** 函数功能:逆转节点的递归函数
** 函数形参:节点的结构体指针
** 返回值  :无
**
*************************************************/
static void reverse(NODE_LIST *head)
{
    if(head && head->next)
    {
        reverse(head->next);
        head->next->next = head;
        head->next = NULL;
    }
}
/*************************************************
**
** 函数名称:list_reverse()
** 函数功能:逆转单向链表
** 函数形参:链表的结构体指针
** 返回值  :无
**
*************************************************/
void list_reverse(LIST* list)
{
    reverse(list->head);
    NODE_LIST *temp = list->head;
    list->head = list->tail;
    list->tail = temp;
}
/*取链表的中间值,只能遍历一次*/
/*利用烧绳子的思路*/
/*一个指针一次跳一个,一个指针一次跳两个*/
/*跳两个指针的到底,mid指针就到中点*/
/*************************************************
**
** 函数名称:list_middle()
** 函数功能:取链表的中间值
** 函数形参:链表的结构体指针
** 返回值  :无
**
*************************************************/
int list_middle(LIST* list)
{
    NODE_LIST *mid = NULL,*node = NULL;
    for(mid=node=list->head;node->next&&node->next->next;
                            node=node->next->next)
    {
        mid = mid->next;
    }
    return mid->data;
}

/*************************************************
**
** 文件名称:node_list.h
** 文件功能:node_list.c
** 文件作者:紫瞳标
** 文件时间:2014-1-8
**
*************************************************/
#ifndef _NODE_LIST_H
#define _NODE_LIST_H
#include <stdio.h>/*写在头文件了*/
/*节点*/
typedef struct NodeList {
    int data;/*数据*/
    struct NodeList *next;/*后指针*/
} NODE_LIST;
typedef struct List {
    NODE_LIST *head;/*头指针*/
    NODE_LIST *tail;/*尾指针*/
} LIST;

NODE_LIST * create_node(int );/*创建节点*/
NODE_LIST * destroy_node(NODE_LIST*);/*销毁节点*/
void list_init(LIST *);/*初始化*/
void list_deinit(LIST *);/*清空*/
void list_append(LIST* ,int);/*追加*/
size_t list_size(LIST*);/*测长*/
void list_print(LIST*);/*正向打印*/
void list_rprint(LIST*);/*反向打印*/
void list_reverse(LIST*);/*逆转链表*/
int  list_middle(LIST*);/*取单向链表的中间值,时间复杂度不能超过O(N)级*/
#endif

makefile 如下
nl:node_list.o nl_test.o
	gcc node_list.c nl_test.o -o nl
node_list.o:
	gcc -c node_list.c
nl_test.o:
	gcc -c nl_test.c
clean:
	rm nl nl_test.o node_list.o
结果演示如下
:~/csdn/day20/node_list$ make
gcc -c node_list.c
gcc -c nl_test.c
gcc node_list.c nl_test.o -o nl
:~/csdn/day20/node_list$ ./nl 
该链表有4个元素
正向打印结果为
23 33 43 53 
反向打印结果为
53 43 33 23 
逆转后正向打印
53 43 33 23 
中间值是43


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值