#include<stdlib.h>
#include<stdio.h>
typedef struct LNode{
int data;
struct LNode *next;
}LNode,*LinkList;
// LNode 强调这是一个结点,*LinkList强调这是一个单链表。
// 头插法
// 头指针的数据域始终为空,位置不动
// 头指针原先的指针域赋值给新插入结点的指针域,然后头指针再指向新插入的结点
LinkList list_insert_head(LinkList &L){
int x;
LNode *p;
L = (LinkList)malloc(sizeof(LNode*));
L->next = NULL;
printf("请输入要结点数值(9999结束):\n");
scanf("%d",&x);
while(x!=9999){
p = (LNode*)malloc(sizeof(LNode));
p->data = x;
p->next = L->next;
L->next = p;
scanf("%d",&x);
}
return L;
}
// 尾插法
// r->next 始终指向新结点,到末尾时,指针域赋值给NULL
// 注意!!!r->next表示r的指针域, r表示尾节点本身
LinkList list_insert_tail(LinkList &L){
int x;
L = (LinkList)malloc(sizeof(LNode));
LNode *p,*r=L;
printf("请输入要结点数值(9999结束):\n");
scanf("%d",&x);
while(x!=9999){
p = (LNode*)malloc(sizeof(LNode));
p->data = x;
r->next = p;
r = p;
scanf("%d",&x);
}
r->next = NULL;
return L;
}
void print_List(LinkList L){
if(!L) return;
L = L->next;
while(L){
printf("%d ",L->data);
L = L->next;
}
}
LinkList deletNode(LinkList L,int val){
if(!L) return NULL;
LNode *p = L;
while(p->next){
if(p->next->data == val){
p->next =p->next->next;
return L;
}
p = p->next;
}
return L;
}
LinkList list_revese(LinkList &L){
LNode *N = L;
LNode *P = NULL;
if(!L) return NULL;
while(L->next){
N = N->next;
L->next = P;
P = L;
L = N;
}
L->next = P;
return L;
}
int main(){
LinkList L1,L2; //L1 L2 指标是链表头,是结构体指针类型
printf("使用头插法创建链表:\n");
list_insert_head(L1);
print_List(L1);
printf("\n");
printf("使用尾插法创建链表:\n");
list_insert_tail(L2);
print_List(L2);
printf("\n");
printf("删除结点,删除【2】:\n");
deletNode(L1,2);
print_List(L1);
printf("\n");
printf("反转链表:\n");
list_revese(L1);
while(L1 &&L1->next){
printf("%d ",L1->data);
L1 = L1->next;
}
printf("\n");
}
头指针和头结点
头指针:链表中第一个结点的存储位置,用来标识单链表
头结点:在单链表中,第一个结点前附加的结点,是为了操作方便
若链表有头结点,则头指针永远指向头结点。
不论链表是否为空,头指针都不为空,头指针时链表的必需元素。而头结点的数据域一般为空,或存放链表长度,头结点不是必须的。
反转链表: