链表可以说是C语言中比较实用的一种,也算是学C的数据结构的基础。比数组的增删改查操作更加灵活方便。
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。
直接上代码加深理解。
此链表包括:
1.在指定位置插入元素(增)
2.删除指定节点的元素(删)
3.返回数据域等于data的节点(查)
4.返回数据域等于data的节点的位置
5.返回链表指定位置的节点
6.得到链表最后一个节点
7.循环遍历链表
8.返回链表元素个数
9.清空链表,只保留首节点
10.返回链表是否为空
#include
#include
// 定义一个结构体
struct list
{
int data; // 数据域
struct list *next; // 指针域
};
// 新建立一个节点
struct list *create_list()
{
return calloc(sizeof(struct list),1);
}
// 在指定位置插入元素(增)
struct list *insert_list(struct list *ls, int n, int data)
{
struct list *p = ls;
while (p && n--) {
p = p->next;
}
if(p == NULL)
{
return NULL; // n的位置大于链表节点数
}
struct list *node = create_list(); // 新建立一个节点
node->data = data;
node->next = p->next;
p->next = node;
return node;
}
// 删除指定节点的元素(删)
int delete_list(struct list *ls, int n)
{
struct list *p = ls;
while (p && n--)
{
p = p->next;
}
if(p == NULL)
return -1; // n的位置不合适
struct list *tmp = p->next;
p->next = p->next->next;
free(tmp);
return 0; // 删除成功
}
// 返回数据域等于data的节点(查)
struct list *elem_locale(struct list *ls, int data)
{
struct list *p = ls;
while (p) {
if(p->data == data)
return p;
p = p->next;
}
retu NULL; // 没有找到
}
// 返回数据域等于data的节点的位置
int elem_pos(struct list *ls, int data)
{
int index = 0;
struct list *p = ls;
while (p) {
index++;
if(p->data == data)
return index;
p = p->next;
}
return -1;
}
// 返回链表指定位置的节点
struct list *local_list(struct list *ls, int n)
{
struct list *p = ls;
while (p && n--) {
p = p->next;
}
if(p == NULL)
return NULL;
return p;
}
// 得到链表最后一个节点
struct list *last_list(struct list *ls)
{
struct list *p = ls;
while (p->next) {
p = p->next;
}
return p;
}
// 循环遍历链表
void traverse(struct list *ls)
{
struct list *p = ls;
while (p) {
printf("%d\n",p->data);
p = p->next; // p指向下一个节点
}
}
// 返回链表元素个数
int count_list(struct list *ls)
{
struct list *p = ls;
int count = 0;
while (p) {
count++;
p = p->next;
}
return count;
}
// 清空链表,只保留首节点
void clear_list(struct list *ls)
{
struct list *p = ls->next;
while (p) {
struct list *tmp = p->next;
free(p);
p = tmp;
}
ls->next = NULL; // 只有首节点,那么首节点的next应该是NULL
}
// 返回链表是否为空
int empty_list(struct list *ls)
{
if(ls->next)
return 0;
else
return -1;
}
int main1()
{
struct list *first = create_list();
struct list *second = create_list();
struct list *third = create_list();
first->data = 1;
second->data = 2;
third->data = 3;
first->next = second;
second->next = third;
// 对于链表的最后一个节点,next域一定为NULL
third->next = NULL;
// 遍历
traverse(first);
return 0;
}
int main2()
{
struct list *first = create_list();
struct list *second = create_list();
struct list *third = create_list();
first->data = 1;
second->data = 2;
third->data = 3;
first->next = second;
second->next = third;
// 对于链表的最后一个节点,next域一定为NULL
third->next = NULL;
// 插入节点
insert_list(first,0,100);
// 遍历
traverse(first);
return 0;
}
int main3()
{
struct list *first = create_list();
struct list *second = create_list();
struct list *third = create_list();
first->data = 1;
second->data = 2;
third->data = 3;
first->next = second;
second->next = third;
// 对于链表的最后一个节点,next域一定为NULL
third->next = NULL;
// 插入节点
insert_list(first,2,100);
// 删除
delete_list(first,2);
// 遍历
traverse(first);
return 0;
}
int main()
{
struct list *first = create_list();
struct list *second = create_list();
struct list *third = create_list();
first->data = 1;
second->data = 2;
third->data = 3;
first->next = second;
second->next = third;
// 对于链表的最后一个节点,next域一定为NULL
third->next = NULL;
// 清空链表
clear_list(first);
// 遍历
traverse(first);
return 0;
}