1、链表的定义
n个节点离散存储,彼此通过指针相连,每个节点都有唯一的前驱节点和后继节点,
首节点没有前驱节点,尾节点没有后继节点。
专业名词
- 首节点:第一个有效节点
- 尾节点:最后一个有效节点
- 头节点:第一个有效节点之前的节点,不存放任何有效数据,目的是为了方便对链表的操作
- 头指针:指向头节点的指针
- 尾指针:指向尾节点的指针
定义语句
typedef struct Node
{
int data; // 数据域
struct Node *pNext; // 指针域,指向了和它数据类型相同的变量
} NODE, *PNODE; // NODE等价于struct Node,PNODE等价于typedef struct Node*
2、链表的分类
- 单链表
- 双链表:每一个节点有两个指针域,既可以指向前驱节点,又可以指向后继节点
- 循环链表:能通过任意一个节点,找到链表的其它所有节点
- 非循环链表
3、算法
1)创建链表
PNODE create_list(void)
{
PNODE phead = (PNODE)malloc(sizeof(PNODE)); // 初始化头节点
if (phead == NULL)
{
printf("初始化失败!");
exit(-1);
}
PNODE pnode = phead;
pnode->pNext = NULL;
int len;
printf("请用户输入链表的长度:\n");
scanf("%d", &len);
for (int i = 0; i < len; i++)
{
int val;
PNODE pnew = (PNODE)malloc(sizeof(PNODE));
printf("你想要输入链表第%d个元素的值是:\n", i + 1);
scanf("%d", &val);
pnew->data = val;
pnode->pNext = pnew;
pnew->pNext = NULL;
pnode = pnew;
}
return phead;
}
2)遍历链表
void traverse_list(PNODE phead)
{
PNODE pnode = phead->pNext;
while (pnode != NULL)
{
printf("%d ", pnode->data);
pnode = pnode->pNext;
}
printf("\n");
}
3)判空
bool isempty(PNODE phead)
{
if (phead->pNext == NULL)
return true;
else
return false;
}
4)求链表的长度
int length(PNODE phead)
{
int count = 0;
PNODE pnode = phead->pNext;
while (pnode != NULL)
{
count++;
pnode = pnode->pNext;
}
return count;
}
5)链表排序
void sort_list(PNODE phead)
{
int len = length(phead);
for (PNODE pnode = phead->pNext; pnode != NULL; pnode = pnode->pNext)
{
int t;
for (PNODE qnode = pnode->pNext; qnode != NULL; qnode = qnode->pNext)
{
if (pnode->data > qnode->data)
{
t = pnode->data;
pnode->data = qnode->data;
qnode->data = t;
}
}
}
return;
}
6)在指定位置前插入一个元素
bool insert_element(PNODE phead, int pos, int val)
{
int i = 0;
PNODE pnew = (PNODE)malloc(sizeof(NODE));
if (pnew == NULL)
printf("动态分配内存失败!");
pnew->data = val;
PNODE pnode = phead;
while (i < pos - 1 && pnode != NULL)//找到插入元素的前驱节点
{
i++;
pnode = pnode->pNext;
}
if (i > pos - 1 || pnode == NULL)
return false;
pnew->pNext = pnode->pNext;
pnode->pNext = pnew;
return true;
}
7)删除指定位置的元素
bool delete_element(PNODE phead, int pos, int *val)
{
int i = 0;
PNODE pnode = phead;
while (i < pos - 1 && pnode->pNext != NULL)//找到删除元素的前驱节点
{
i++;
pnode = pnode->pNext;
}
if (i > pos - 1 || pnode->pNext == NULL)
return false;
PNODE p = pnode->pNext;
*val = p->data;
pnode->pNext = pnode->pNext->pNext;
free(p);
return true;
}
main函数
int main()
{
int val;
PNODE phead;
phead = create_list();
traverse_list(phead);
if (isempty(phead))
{
printf("该链表为空\n");
}
else
printf("该链表不为空!\n");
int len = length(phead);
printf("该链表的长度为%d\n", len);
sort_list(phead);
traverse_list(phead);
insert_element(phead, 2, 55);
traverse_list(phead);
delete_element(phead, 2, &val);
traverse_list(phead);
return 0;
}