/*
* singly_linked_list.c
* 单向链表
* sll = singly_linked_list
* */
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
/*
* 节点结构 head -> |value|next| -> ...
* */
typedef struct sll {
int value;
struct sll *next;
} sll;
void init_sll(sll **head);
void add_sll_node(sll **head, int value);
void add_sll_nodes(sll **head, int values[], int len);
bool del_sll_node(sll **head, int index);
sll *get_sll_node(sll *head, int index);
sll *locate_sll_node(sll *head, int value);
bool insert_sll_node(sll **head, int index, int value);
void traverse_sll(sll *head);
int length_sll(sll *head);
int main(int argc, char *argv[])
{
sll *head;
init_sll(&head);
add_sll_node(&head, 1);
int values[] = {1, 2, 3, 5, 8, 13};
add_sll_nodes(&head, values, 6);
traverse_sll(head);
del_sll_node(&head, 0);
del_sll_node(&head, 3);
traverse_sll(head);
printf("The %d node is %p
", 4, get_sll_node(head, 4));
printf("The node with value %d is %p
", 13, locate_sll_node(head, 13));
printf("Length of List: %d
", length_sll(head));
insert_sll_node(&head, 0, 0);
insert_sll_node(&head, length_sll(head), 21);
traverse_sll(head);
del_sll_node(&head, 4);
traverse_sll(head);
return 0;
}
/*
* 初始化链表
* 要求传入一个链表指针的地址,以便在函数中对这个指针做出更改
* */
void init_sll(sll **head)
{
*head = NULL;
}
/*
* 添加节点
* */
void add_sll_node(sll **head, int value)
{
/* 新建一个节点 */
sll *node = (sll *)malloc(sizeof(sll));
node->value = value;
node->next = NULL;
sll *last = *head;
if (!last) {
/* 如果head节点是空的,说明链表为空 */
*head = node;
} else {
/* 找到链表尾部,将last节点的next指向sll节点 */
while (last->next) {
last = last->next;
}
last->next = node;
}
}
/*
* 增加多个节点
* */
void add_sll_nodes(sll **head, int values[], int len)
{
for (int i = 0; i < len; i++) {
add_sll_node(head, values[i]);
}
}
/*
* 根据索引删除节点
* 删除成功返回true,否则返回false
* */
bool del_sll_node(sll **head, int index)
{
/* 如果删除索引大于等于列表长度 */
if (index >= length_sll(*head))
return false;
/* 删除首节点 */
if(index==0) {
sll *first = *head;
sll *second = first->next;
free(first);
first = NULL;
*head = second;
return true;
} else {
/* 遍历到index的前一位后执行删除操作 */
int count = 0;
for (sll *p=*head; p; p=p->next) {
count++;
if (count == index) {
sll *n = p->next;
p->next = n->next;
free(n);
n = NULL;
return true;
}
}
}
return false;
}
/*
* 根据索引查找节点
* 从0开始算起
* */
sll *get_sll_node(sll *head, int index)
{
/* 重复往下寻找index次,找到第index个节点,返回节点地址,否则NULL */
sll *node = head;
int j = 0;
while (node->next != NULL && j < index)
{
node = node->next;
j++;
}
if (j == index)
return node;
else
return NULL;
}
/*
* 后插法:找到index-1位置,将节点插入到index中去
* 在index位置插入value
* */
bool insert_sll_node(sll **head, int index, int value)
{
/*
* 如果index为0,需要改变head指向
* */
if (index == 0) {
sll *node = (sll *)malloc(sizeof(sll));
node->value = value;
node->next = *head;
*head = node;
return true;
}
/*
* 找到index-1位置的节点,如果节点不存在,不能插入
* */
sll *p, *s;
p = get_sll_node(*head, index-1);
if (p == NULL) {
printf("wrong index
");
return false;
} else {
/*
* 新建节点s
* s->next指向原先p->next
* p->next指向s
* */
s = (sll *)malloc(sizeof(sll));
s->value = value;
s->next = p->next;
p->next = s;
return true;
}
}
/*
* 根据值查找节点
* */
sll *locate_sll_node(sll *head, int value)
{
for (sll *p=head; p; p=p->next) {
if (p->value == value)
return p;
}
return NULL;
}
/*
* 遍历打印链表
* */
void traverse_sll(sll *head)
{
for (sll *p=head; p; p=p->next) {
printf("%d -> ", p->value);
}
printf("NULL
");
}
/*
* 链表长度
* */
int length_sll(sll *head)
{
int len = 0;
for (sll *p=head; p; p=p->next) {
len++;
}
return len;
}