一:什么是链表:
定义:
不使用连续的内存空间,而是使用指针的形式将每一个数值建立起次序关系的一种数据结构。由于各个数据之间并不是物理意义上的相邻,所以对于存储和运行的效率比顺序表要快速。在插入和删除等操作时也不需要将数据大量移动。
特点:
相邻元素的地址并不相连,而是用指针相连接。
二:单链表的常用操作:
什么是单链表:
单链表是通过任意的存储空间来存储数据元素。对于一个数据元素,不仅要存放自身代表的数据,还要存放后继元素的地址,使前一个数据可以指向后继数据。
由于每个结点都有一个指向后继的数据,可以通过第一个数据往后查找任意数量的元素,所以叫做单链表。
通过单链表的第一个结点的地址就可以访问第一个元素,通过第一个结点的指向后继元素的指针就可以得到第二个数据的地址……以此类推直到最后一个结点。此时,称第一个元素的地址为“头指针”。
(1):定义单链表:
typedef struct node{
int data; //元素
struct *next; //后继指针
}LNode,*LinkList; //定义单链表结构体和相应的指针结构体
(2):初始化单链表:
LinkList Init_LinkList()
{
LinkList H; //头指针
H = (LinkList)malloc(sizeof(LNode)); //分配动态空间
if(H)
H->next = NULL; //初始定位NULL
return H;
}
(3):单链表的表长:
由于单链表的数据之间并不是物理上的相邻,所以并不能像顺序表一样直接定义一个变量记录表长,需要从头结点开始遍历。
int Len_LinkList(LinkList H)
{
LinkList p = H; //p指向头节点
int cnt = -1; //计数器
while(p) //遍历
{
p = p->next;
cnt++;
}
return cnt;
}
(4):按位置查找:
单链表的按位置查找操作需要从第一个节点开始遍历,找到对应的位置数据,然后进行输出。
LinkList Find_Link_Pos(LinkList H,int i)
{
LinkList p;
int j = 0;
p = H;
while(p && j<i) //开始查找,直到遍历到目标位置前一个结点
{
p = p->next; //往后寻找
j++;
}
if(j != i || !p) //退出上一个循环时,如果到了正确位置,j == i
{
printf("错误");
return NULL;
}
return p; //返回指针
}
(5):按数值查找:
单链表的按数值查找和按位置查找一样,也需要从第一个结点开始遍历。
LinkList Find_Link_Val(LinkList H,int x)
{
LinkList p = H->next; //p指针指向第一个元素
while(p && p->data != x) //指针存在,并且数据不匹配
p = p->next; //指向下一个位置
return p;
}
(6):单链表的插入:
由于单链表每一个节点都有一个额外指针指向后继结点,所以对于结点的插入需要对于后继指针也进行相应操作。
具体操作为:
1.将新节点的指针指向插入位置的前一个结点的指针指向的后继结点,
2.再将插入位置的前一个结点的指针指向插入的新节点,将新节点作为这个元素的后继结点。
int Insert_LinkList(LinkList H,int i,int x)
{
LinkList p,q;
p = Find_Link_Pos(H,i-1); //遍历相应位置
if(!p)
{
printf("错误");
return 0;
}
q = (LinkList)malloc(sizeof(LNode)); //给新节点分配空间
if(!q)
{
printf("分配空间失败");
return 0;
}
q->data = x;
/*关键代码*/
q->next = p->next;
p->next = q;
return 1;
}
(7):单链表的删除:
同样是因为单链表一个节点有指针指向后继结点,对于单个结点的删除,也需要对对应位置前后的结点指针进行改变。
具体操作为:
1.将删除结点的前一个结点的指针指向删除结点的后一个结点。
2.释放删除结点的空间。
int Pop_LinkList(LinkList H,int i)
{
LinkList p,q;
if(H == NULL || H->next == NULL) //链表不存在
{
printf("错误");
return 0;
}
p = Find_Link_Pos(H,i-1); //查找删除位置
if(p == NULL || p->next == NULL)
{
printf("错误");
return 0;
}
/*关键代码*/
q = p->next;
p->next = q->next;
free(q);
return 1;
}