数据结构学习之路(C语言)
- 第一部分 线性表之数据表(数组);
- 第二部分 线性表之单链表;
- 第三部分 栈;
- 第四部分 队列;
第二部分:链表(主要指单链表)
简介:与前一章节提到的顺序表不同的是,顺序表的存储格式是数组,是用一篇连续的内存空间来存储数据。而链表的存储形式是一个个在内存中地址不连续的节点来组成的,各个节点之间通过指针关联起来。
注:以下是代码部分,实现了单链表的各种操作
1.构建链表节点的基本格式(未分配内存)
typedef int data_t;
typedef struct node
{
data_t data;
struct node *next;
}listnode,*linklist;
2.创建一个链表节点
linklist linknode_create()
{
linklist H = (linklist)malloc(sizeof(listnode));
if(H == NULL)
{
printf("malloc failed\n");
}
H->data = 0;
H->next = NULL;
return H;
}
3.链表尾部插入
int linklist_tail_insert(linklist H,data_t value)
{
linklist new_node = (linklist)malloc(sizeof(listnode));
if(new_node == NULL)
{
printf("malloc failed\n");
return -1;
}
new_node->data = value;
new_node->next = NULL;
while(H->next != NULL)
{
H = H->next;
}
H->next = new_node;
return 0;
}
4.链表头部插入
int linklist_head_insert(linklist H,data_t value)
{
if(H == NULL)
{
printf("malloc failed\n");
return -1;
}
linklist new_node = (linklist)malloc(sizeof(listnode));
if(new_node == NULL)
{
printf("malloc failed\n");
return -1;
}
new_node->data = value;
new_node->next = H->next;
H->next = new_node;
return 0;
}
5.删除链表中的元素
int linknode_delete(linklist H,int pos)
{
int i = 0;
int length;
if(pos == 0)
{
printf("not delete head\n");
}
if(linklist_get_length(H,&length) == 0)
{
if(pos > length)
{
printf("pos error\n");
return -1;
}
}
while(i<pos-1)
{
H = H->next;
i++;
}
if(H->next->next != NULL)
{
H->next = H->next->next;
}
else
{
H->next == NULL;
}
return 0;
}
6.迭代方法遍历链表数据(iterate)
//iterate
int linklist_show(linklist H)
{
if(H == NULL)
{
printf("malloc failed\n");
return -1;
}
while(H->next != NULL)
{
printf("%d ",H->next->data);
H = H->next;
}
puts("");
return 0;
}
7.求当前链表的长度
int linklist_get_length(linklist H,int * length)
{
*length = 0;
while(H->next != NULL)
{
(*length)++;
H = H->next;
}
return 0;
}
8.在链表任一有效位置插入元素
int linklist_insert(linklist H,data_t value ,int pos)
{
int i = 0;
int length = 0;
linklist new_node = (linklist)malloc(sizeof(linklist));
new_node->data = value;
linklist_get_length(H,&length);
while(i < pos-1)
{
H = H->next;
i++;
}
new_node->next = H->next;
H->next = new_node;
return 0;
}
9.迭代法翻转列表
int linklist_reverse(linklist h)
{
linklist q = h;
linklist current = h;
linklist pre = NULL;
linklist next = current->next;
if(h == NULL)
{
printf("invaild linklist\n");
return -1;
}
while(next != NULL)
{
current = next;
next = current->next;
current->next = pre;
pre = current;
}
h->next = current;
return 0;
}
10.递归法遍历列表
//recursion
int linklist_recursion_show(linklist H)
{
H = H->next;
if(H == NULL)
{
puts("");
return -1;
}
printf("%d ",H->data);
linklist_recursion_show(H);
return 0;
}
11.递归法翻转列表
// recursion reversion
int linklist_reverse_recursion(linklist h,linklist H)
{
h = h->next;//1 2 3 4 null
if(h == NULL)
{
printf("come here\n");
return -1;
}
linklist_reverse_recursion(h,H);//4 3 2
if(h->next != NULL)
{
linklist q = h->next;// 4
q->next = h; //changed
h->next = NULL;//changed
}
else
{
H->next = h;
}
return 0;
}
主函数业务逻辑实现
int main()
{
int value;
int length = 0;
linklist head = linknode_create();
if(head == NULL)
{
printf("headlist create failed\n");
return -1;
}
printf("input:");
scanf("%d",&value);
while(value != -1)
{
printf("input:");
//linklist_tail_insert(head,value);
linklist_head_insert(head,value);
scanf("%d",&value);
}
linklist_show(head);
if(linklist_get_length(head,&length) == 0)
{
printf("%d\n",length);
}
linknode_delete(head,2);
linklist_show(head);
if(linklist_get_length(head,&length) == 0)
{
printf("%d\n",length);
}
linklist_insert(head,100,length);
linklist_show(head);
change_value(head);
linklist_show(head);
linklist_reverse(head);
linklist_show(head);
linklist_recursion_show(head);
linklist_reverse_recursion(head,head);
linklist_show(head);
return 0;
}
总结
本文介绍了对数据结构中链表的常用操作,函数和结构体声明在linklist.h
文件中,具体的函数实现在linklist.c
文件中,函数调用,逻辑实现在test.c
文件中。
关于栈的实现和操作,请关注下篇文章。