数据结构——链表——单链表(C语言实现)
·
单链表——初始化
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<string.h>
#define MAXSIZE 100
typedef int Elemtype;
//单链表初始化——直接在堆区创建
typedef struct Node
{
Elemtype data;
struct Node* next;
}Node;
Node* initList()
{
Node* head = (Node*)malloc(sizeof(Node));
head->data = 0;
head->next = NULL;
return head;
}
int main()
{
Node* List = initList();
return 1;
}

单链表——头插法

//头插法
int insertHead(Node* L,Elemtype e)
{
Node* p = (Node*)malloc(sizeof(Node));
p->data = e;
p->next = L->next;
L->next = p;
}
int main()
{
Node* list = initList();
insertHead(list, 10);
insertHead(list, 20);
}
单链表——遍历
注意:下面的L指的是头节点,头节点的next是首元节点,才是链表存数据的第一个
//遍历
void listNode(Node* L)
{
Node* p = L->next;//L为头节点,L的next指向的是首元节点
while (p != NULL)
{
printf("%d", p->data);
p = p->next;
}
printf("\n");
}
单链表——尾插法
相比于头插法,要先找到尾部,找到节点next指向是NULL的节点
//尾插法
//先找到尾节点,获取尾节点
Node* get_tail(Node* L)
{
Node* p = L;
while (p->next !=NULL)
{
p = p->next;
}
return p;
}
//尾插
Node* insertTail(Node* tail, Elemtype e)
{
Node* p = (Node*)malloc(sizeof(Node));
p->data = e;
tail->next = p;
p->next = NULL;
return p;
}
单链表——在指定位置插入数据
//在指定位置插入数据
int insertNode(Node* L, int pos, Elemtype e)//L链表,pos是插入的位置,e是插入的新数据
{
//用来保存插入位置的前驱节点
Node* p = L;
int i = 0;
//遍历链表找到插入位置的前驱节点
while (i<pos-1)
{
p = p->next;
i++;
if (p == NULL)
{
return 0;
}
}
Node* q = (Node*)malloc(sizeof(Node));
q->data = e;
q->next = p->next;
p->next = q;
return 1;
}
单链表——删除节点
找到要删除节点的前置节点p
用指针q记录要删除的节点
通过改变p的后继节点实现删除
释放删除节点的空间
//删除节点
int deleteNode(Node* L, int pos)
{
//要删除节点的前驱节点
Node* p = L;
int i = 0;
//遍历链表,找到要删除节点的前驱节点
while (i < pos - 1)
{
p = p->next;
i++;
if (p == NULL)
{
return 0;
}
}
if (p->next ==NULL)
{
printf("要删除的位置错误\n");
return 0;
}
//q指向要删除的节点
Node* q = p->next;
//让要删除节点的前驱指向要删除节点的后继
p->next = q->next;
//释放要删除节点的空间
free(q);
return 1;
}
单链表——获取链表长度
//获取链表长度
int listlength(Node* L)
{
Node* p = L;
int len = 0;
while (p !=NULL)
{
p = p->next;
len++;
}
return len;
}
单链表——释放链表
指针p指向头节点后的第一个节点
判断指针p是否指向空节点
如果p不为空,用指针q记录指针p的后继节点
释放指针p指向的节点
指针p合指针q指向同一个节点,循环上面操作
//释放链表
void freeList(Node* L)//传进来链表,也就是头节点
{
Node* p = L->next;
Node* q;
while (p != NULL)
{
q = p->next;
free(p);
p = q;
}
L->next = NULL;//头节点指向空
}
单链表应用——反转链表

先拿first指向空值,再拿second指向1,third指向second所指向的下一个节点

然后让second指向空值

然后挪动三个指针

再将此时的2指针指向改变

依次进行,直到second指向空值

再安一个头节点

//反转链表
Node* reverseList(Node* head)
{
Node *first = NULL;
Node *second = head->next;
Node *third;
while(second != NULL)
{
third = second->next;
second->next = first;
first = second;
second = third;
}
Node *hd = initList();
hd->next = first;
return hd;
}
int main(int argc, char const *argv[])
{
Node *list = initList();
Node *tail = get_tail(list);
tail = insertTail(tail, 1);
tail = insertTail(tail, 2);
tail = insertTail(tail, 3);
tail = insertTail(tail, 4);
tail = insertTail(tail, 5);
tail = insertTail(tail, 6);
listNode(list);
Node* reverse = reverseList(list);
listNode(reverse);
return 0;
}
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)