C编程——单向链表
主要概念:
单向链表数据结构及功能图示:
实验目的:
实现一个单向链表,并且实现添加、删除、打印的功能。
主要函数:
node * create_list(void); //创建链表头
node * create_node(student *per_info); //创建节点
void print_list(node *phead); //打印链表
void insert_by_head(node *phead, student *per_info); //从头部插入节点
void delete_node_by_id(node *phead, int num); //通过id删除一个节点
代码:
//single_list.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct student{
char name[20];
int id;
int score;
} student;
typedef struct node{
student data;
struct node *pnext;
}node;
node * create_list()
{
node *phead = (node *)malloc(sizeof(node));
if(NULL == phead)
{
printf("malloc error!\n");
return NULL;
}
memset(phead, 0, sizeof(node));
phead->pnext = NULL;
return phead;
}
node * create_node(student *per_info)
{
node *newnode = (node *)malloc(sizeof(node));
if (NULL == newnode)
{
printf("malloc error!\n");
return NULL;
}
memset(newnode, 0, sizeof(node));
newnode->data = *per_info;
newnode->pnext = NULL;
return newnode;
}
void print_list(node *phead)
{
node *p = phead;
if(p->pnext == NULL)
printf("print error:the linked list is empty!\n");
else {
//printf("姓名\t序号\t分数:\n");
while(p->pnext != NULL)
{
p = p->pnext;
printf(" %s\t\t%d\t\t%d\n", p->data.name, p->data.id, p->data.score);
}
}
}
void insert_by_head(node *phead, student *per_info)
{
node *newnode = create_node(per_info);
if(phead->pnext == NULL)
{
phead->pnext = newnode;
newnode->pnext = NULL;
} else {
newnode->pnext = phead->pnext; //注意这两句顺序不能反!
phead->pnext = newnode;
}
//printf("Insert %s to head successfully!\n", newnode->data.name);
}
void delete_node_by_id(node *phead, int num)
{
node *pmov = phead->pnext;
node *pmov_front = phead;
//1.判断是否为空链表
if(NULL == pmov)
{
printf("delete error:the linked list is empty!\n");
} else {
while (pmov->data.id != num)
{
if(NULL == pmov->pnext)
{
printf("error:cannot find this node.please confirm the data's validity!\n");
return;
}
pmov_front = pmov;
pmov = pmov->pnext;
}
pmov_front->pnext = pmov->pnext;
free(pmov);
}
}
int main()
{
node *ph = create_list();
student init_struc = {{'\0'}, 0, 0};
student *stu = &init_struc;
char choice = 0;
while(1)
{
printf("请依次输入学生的 姓名\t序号\t分数: ");
scanf("%s %d %d", stu->name, &(stu->id), &(stu->score));
insert_by_head(ph, stu);
printf("continue?(Y/N)\n");
setbuf(stdin,NULL);
choice = getchar();
if(choice == 'N' || choice == 'n')
break;
choice = 0;
}
printf("姓名\t\t序号\t\t分数:\n");
print_list(ph);
//delete_node_by_id(ph, 2);
//print_list(ph);
return 0;
}
编译运行:
sixer@ubuntu:~/imx_usr/sys_app/test$ gcc -o single_list single_list.c
sixer@ubuntu:~/imx_usr/sys_app/test$ ./single_list `
实验现象:
请依次输入学生的 姓名 序号 分数: sixer 01 98
continue?(Y/N)
y
请依次输入学生的 姓名 序号 分数: zac 20 76
continue?(Y/N)
n
姓名 序号 分数:
zac 20 76
sixer 1 98
总结:
整体完成了单项链表的基本功能。后续还可以添加搜索,修改等功能,且链表节点数据student结构可用指针替代,写成一个通用的单项链表功能模块。