我们至少可以通过两种结构来存储数据
> 数组:
- 优点:
存取速度快
- 缺点:
需要一个连续的很大的内存
插入和删除元素的效率很低
> 链表
- 专业术语:
首节点:
存放第一个有效数据的节点
尾节点:
存放最后一个有效数据的节点
头结点:
头结点的数据类型和节点的类型是一模一样的
头结点是首节点前面的那个节点
头结点并不存放有效数据
设置头结点的目的是为了方便对链表的操作
头指针:
存放头结点地址的指针变量
- 确定一个链表需要一个参数:
头指针
- 优点:
插入删除元素效率高
不需要一个连续的很大的内存
- 缺点:
查找某个位置的元素效率低
链表举例:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
//定义可一个链表节点的数据类型
struct Node
{
//数据域
int date;
//指针域
struct Node * pNext;
};
//函数声明
struct Node * create_list(void);
bool empty_list(struct Node *);
void traverse_list(struct Node *);
int main(void)
{
struct Node * pHead = NULL;
//create_list功能:创建一个非循环单链表,并将头结点赋予pHead
pHead = create_list();
//traverse_list功能:输出链表
traverse_list(pHead);
//释放内存
free(pHead);
return 0;
}
struct Node * create_list(void)
{
//用来存放有效节点的个数
int len;
int i;
//用来临时存放用户输入的结点的值
int val;
//分配了一个不存放有效数据的头结点
struct Node * pHead = (struct Node *)malloc(sizeof(struct Node));
if (NULL == pHead)
{
printf("分配失败,程序终止!\n");
//终止程序
exit(-1);
}
struct Node * pTail = pHead;
pTail->pNext = NULL;
printf("请输入您需要生成的链表节点的个数:len = ");
scanf("%d", &len);
for (i=0; i<len; ++i)
{
printf("请输入第%d个节点的值: ", i+1);
scanf("%d", &val);
struct Node * pNew = (struct Node *)malloc(sizeof(struct Node));
if (NULL == pNew)
{
printf("分配失败,程序终止!\n");
//终止程序
exit(-1);
}
pNew->date = val;
pTail->pNext = pNew;
pNew->pNext = NULL;
pTail = pNew;
}
return pHead;
}
bool empty_list(struct Node * pHead)
{
if (pHead->pNext == NULL)
return true;
else
return false;
}
void traverse_list(struct Node * pHead)
{
struct Node * p = pHead->pNext;
while (NULL != p)
{
printf("%d ", p->date);
p = p->pNext;
}
printf("\n");
return;
}
/*
在Microsoft Visual Studio 2010的过程:
-----------------------------------
请输入您需要生成的链表节点的个数:len = 3
请输入第1个节点的值: 1
请输入第2个节点的值: 2
请输入第3个节点的值: 3
1 2 3
请按任意键继续. . .
-----------------------------------
总结:
... ...
*/
如有不对或者疏漏的地方,请多多指出。谢谢(⁄ ⁄•⁄ω⁄•⁄ ⁄)