#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct Node
{
int data;
struct Node *next;
}Node;
typedef struct Node *LinkList;
void CreateList(LinkList *L,int n)
{
LinkList p,r;
*L = (LinkList)malloc(sizeof(Node));
r = *L;
int i,a;
for(i=0;i<n;i++)
{
scanf("%d",&a);
p = (Node *)malloc(sizeof(Node));
p->data=a;
r->next = p;
r = p;
}
r->next= NULL;
}
int main()
{
LinkList L,m;
//*L = (Node *)malloc(sizeof(Node));
int n;
scanf("%d",&n);
CreateList(&L,n);
m = L->next;
int i=0;
while(i<n)
{
printf("%d",m->data);
m = m->next;
i++;
}
return 0;
}
1.首先链表必须定义结构体,
typedef struct Node
{
int data;
struct Node *next;
}Node;
定义一个结构体内指针,
struct Node *next;
然后就是创建指针,在一个函数内封装首节点,
void CreateList(LinkList *L,int n)
{
LinkList p,r;
*L = (LinkList)malloc(sizeof(Node));
r = *L;
int i,a;
for(i=0;i<n;i++)
{
scanf("%d",&a);
p = (Node *)malloc(sizeof(Node));
p->data=a;
r->next = p;
r = p;
}
r->next= NULL;
}
这是头指针,按头指针第一个,其它节点按次序插入。
首先定义,*L,r指针,为(*L)分配内存空间,通过移动r指针移动到队尾,就不用移动(*L)指针了,好处。
然后就是for循环,不断定义新的节点,分配内存空间,然后就是让r(位置处于头指针)链接到p节点r->next = p,再再移动尾指针
r = p; 让队尾指针为NULL,r->next= NULL;这是尾插法
接下来看一个尾插法,
LinkList create(LinkList L, int n)
{
LinkList p, s;
L = (LinkList)malloc(sizeof(Node));
if (!L)
{
return NULL;
}
L->next = NULL;1
int i;
for (i = n; i >= 1; i--)
{
p = (Node*)malloc(sizeof(Node));
if (!p)
{
return NULL;
}
p->data = i;
p->next = L->next;2
L->next = p;3
}
return L;
}
尾插法的要义就是,不断插入两个节点之间,给一个节点分配内存空间后,不断利用头指针1,1的L->next = NULL,2来为后续节点的
p->next指向空,3然后再把L->next=p链接起来。
双向循环链表,首先定义结构,
typedef struct node
{
int data;
struct node *prior;//头指针
struct node *next;//尾指针
}
创建双向循环链表和创建单链表一样,关键讲下,双向循环链表插入和删除。其次顺序很重要哦,不能随便改变。
1.s-prior = p;
2.s-next = p->next;
3.p - next-prior = s;
4.p-next = s;
2.3步用到了,p->next,如果第4步提前,就会让p->next变成s提前。
1.p-prior-next = p->next;
2.p->next-prior = p-prior;
3.free(p);这个顺序不能乱。否则p-next失效。
其实双向链表就是让一个节点的前驱和后继都补齐,
再补充一点,就是对结构体指针的理解(链表学的好不好应该就是这了),
LinkList*L 当它为形参数时,这需要传入一个一级指针的地址
LinkList L, &L传入
这是一个二级指针,因为LinkList L,这个定义L,L本身就是一个一级指针。