单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素.
以结点来表示,每个结点是由元素 + 指针组成.
以结点的序列表示线性表称作线性链表(单链表),单链表是链式存取的结构.
单链表设头指针head指向开始结点
/**
创建一个单链表
*/
typedef struct _Sample_List
{
int Data;
struct _Sample_List *next;
}Sample_List;
/**
初始化一个头结点
@return 返回一个链表
*/
Sample_List *Create_Link()
{
Sample_List *head;
head = (Sample_List *)malloc(sizeof(Sample_List));
if (head == NULL) {
perror("malloc:");
}
head->Data = 0;
head->next = NULL;
return head;
}
/**
顺序插入一个节点
@param head 头结点
@param value 插入值
@return 返回一个新链表
*/
int Inser_Link(Sample_List *head, int value)
{
Sample_List *current = head;
Sample_List *New;
New = (Sample_List *)malloc(sizeof(Sample_List));//开辟空间
if (New == NULL) {
perror("malloc new");
}
New->Data = value;
while ((current->next != NULL) && (value > current->next->Data)) {
current = current->next;
}
if (current->next == NULL) {//查找到最后一个开始插入
current->next = New;
New->next = NULL;
}else{
New->next = current->next;//这个是中间插入,比较绕
current->next = New;
}
return 0;
}
/**
单链表的打印
@param head 表头
*/
void sample_List_display(Sample_List *head)
{
for (; head; head = head->next) {
printf("%d", head->Data);
printf("\n");
}
}
int main(int argc, char * argv[]) {
Sample_List d = {1000,0},c = {100, &d},b= {10, &c}, a = {1, &b};
Inser_Link(&a, 20);
Inser_Link(&a, 2000);
sample_List_display(&a);
return 0;
}
1
10
20
100
1000
2000
这里的顺序插入,一种是在最后插入,一种是在中间插入,在中间插入有点绕.我们用一个图片来说明
/**
删除已有的节点
@param head 头节点
@param value 删除值
@return 返回新链表
*/
int Delete_Note(Sample_List *head, int value)
{
Sample_List *history = head;
Sample_List *current = head->next;
while ((current != NULL) && (current->Data != value)) {
history = current;
current = current->next;
}
if (current == NULL) {
if (head->next == NULL) {
printf("list is empty");
}else{
printf("not find this node");
}
return -1;
}else{
history->next = current->next;//删除替换指针
free(current);
printf("delete this node success");
}
return 0;
}
有关于删除链表需要替换掉对应指针
/**
查找任意一个节点
@param head 头节点
@param key 查找值
@return 返回 -1 失败 0 成功
*/
int Search_Link(Sample_List *head, int key)
{
Sample_List *current = head->next;
while ((current != NULL) && (current->Data) != key) {
current = current->next;
}
if (current == NULL) {
if (head->next == NULL) {
printf("link is empty");
}else{
printf("not find");
}
return -1;
}else{
printf("find success!");
}
return 0;
}
/**
链表逆序(逆置)
@param head 头节点
@return 返回新链表
*/
Sample_List *Reverse_Link(Sample_List *head)
{
Sample_List *current,*record;
if (head->next == NULL || head->next->next == NULL) {
return head;
}
current = head->next;
head->next = NULL;
while (current != NULL) {
record = current->next;//这个地方比较绕
current->next = head->next;//当前节点后驱前指
head->next = current;//一直执行当前的点
current = record; //指针后移
}
return head;
}
/**
遍历链表各个节点
@param head 头节点
*/
void Print_Link(Sample_List *head)
{
Sample_List *current = head->next;
printf("各个节点:\n");
while (current != NULL) {
printf("%d->",current->Data);
current = current->next;
}
}
/**
获取链表长度,多少个节点
@param head 头节点
@return 返回长度
*/
int Length_Link(Sample_List *head)
{
Sample_List *current = head->next;
int count = 0;
while (current != NULL) {
count++;
current = current->next;
}
return count;
}
/**
释放链表
@param head 头节点
*/
void Free_Link(Sample_List *head)
{
Sample_List *current = head->next;
Sample_List *record = head;
while (current != NULL) {
record = current;
current = current->next;
free(record);
}
free(head);
printf("free success");
exit(0);
}
参考:https://blog.youkuaiyun.com/mr_chenping/article/details/8224141
https://www.jianshu.com/p/9d017562bfb9