一、单链表
在单链表中,每个节点都包括两个域,即数据域,指针域,也就是说每个节点都包含一个指向下一个节点的指针,链表中的最后一个节点的指针字段的值为NULL,提示链表后面不再有其他节点。遍历链表自始自终都是从头结点开始,就可以访问所有的节点。为了记住链表的起始位置,可以使用一个根节点,根节点的指针域始终指向第一个节点。注意根节点的数据域可以有,也可以没有。
二、程序示例
/*linklist*/
#include <stdio.h>
#include <stdlib.h>
typedef struct NODE
{
struct NODE *next;
int val;
}Node;
/*创建链表,初始化为5,10,15*/
int create_list(Node **header)//指针的指针传递动态内存
{
int i;
Node *temp;
*header = (Node *)malloc(sizeof(Node));
(*header)->next = NULL;
for (i=15; i>0; i-= 5)//第一次molloc的节点为尾节点,
{ //然后往头结点与下一个相邻的节点之间插入新节点
temp = (Node *)malloc(sizeof(Node));
temp->val = i;
temp->next = (*header)->next;
(*header)->next = temp;
}
return 0;
}
/*插入链表中第一个比new_val大的值之前*/
Node *insert(Node **pre, int new_val)
{
Node *new;
Node *cur;
Node *head;
int i = 0;//记录节点的位置
new = (Node *)malloc(sizeof(Node));
cur = *pre;
head = *pre;//备份,用于返回指向第一个节点的指针
while(cur && (cur->val<new_val))//注意先后顺序cur要在前面优先判断,
{ //执行cur->val之前保证cur不是NULL
pre = &cur->next;
cur = *pre;
i++;
}
if (cur==NULL)
{
printf("not exist!\n");
exit(1);
}
new->val = new_val;
new->next = cur;
*pre = new;
if (i==0)
head = new; //(头结点被更改)返回指向第一个节点的指针
return head;
}
/*删除链表中第一个比value大的值*/
Node *delete(Node **pre, int value)
{
Node *cur;
Node *head;
int i = 0;
cur = *pre;
head = *pre;
while(cur && (cur->val<value))
{
pre = &cur->next;
cur = *pre;
i++;
}
if (NULL==cur)
{
printf("not exist!\n");
exit(1);
}
*pre = cur->next;
free(cur);
if (i==0)
head = *pre; //(头结点被更改)返回指向第一个节点的指针
return head;
}
/*打印链表*/
int display(Node *p, int len)
{
int i;
for (i=0; i<len; i++)//从第一个节点开始操作
{
printf("%d\n",p->val);
p = p->next;
}
return 0;
}
int main(void)
{
Node *head = NULL;//头节点
int i;
Node *p;
create_list(&head);
p = head->next;//第一个节点
printf("original list:\n");
display(p, 3);
p = insert(&p,3);
printf("after insert list:\n");
display(p, 4);
p = delete(&p,12);
printf("after delete list:\n");
display(p, 3);
return 0;
}