首先声明一个结构体,里面包含结点内容和结点指针两块;
struct Node
{
char name[10];//学生姓名
int age;//学生年龄
struct Node* next;//结点中指向下一个结点的指针
}
typedef struct Node listNode//重命名结构体
//创建链表
listNode * creatlist(listNode * head,int n);//声明,head代表头结点指针,n代表创建的结点个数
listNode * creatlist(listNode * head, int n)
{
listNode *p;//创建一个结点指针p
head=(listNode *)malloc(sizeof(listNode));//由于需要用到head,现在为head头结点开辟内存空间
head->next=null;
//循环创建
for(int i=1;i<=n;i++)
{
p=(listNode *)malloc(sizeof(listNode));//为将要创建的p结点开辟内存
printf("input the name of %d stu",i);
scanf("%@",&p->name);
printf("input the age of %d stu",i);
scanf("%d",&p->age);
head->next=p;
p=head;//p创建完成之后,头结点变成了p;
}
p->next=null;//将最后结点的指针清空;
return head;//返回链表头结点;
}
//插入节点
void insertNode(int i,listNode *head,int n);//i代表要插入的位置,head代表头结点,n代表链表长度
void insertNode(int i,listNode *head,int n)
{
listNode * p,*q;//声明两个链表结点指针
//对插入的位置的合法性做出判断
if(i<1||i>n+1)
{
printf("ERROR!");
}
else{
int j=0;
p=head;
while(j<i-1)
{
//找到要插入的结点的位置
p=p->next;
j++
}
//为要插入的结点q开辟空间
q=(listNode *)malloc(sizeof(listNode));
scanf("%s",&p->name);
scanf("%d",&p->age);
//将结点q插进去
q->next=p->next;
p->next=q;
}
}
//删除结点
void deleteNode(int i,listNode *head,int n);//i代表要删除的位置,head代表头结点,n代表链表长度
void deleteNode(int i,listNode *head,int n)
{
listNode * p,*q;//声明两个链表结点指针
//对删除的位置的合法性做出判断
if(i<1||i>n)
{
printf("ERROR!");
}
else{
int j=0;
p=head;
while(j<i-1)
{
//找到要删除的结点的位置
p=p->next;
j++
}
//删除结点p->next=q;
p->next=q->next;
//释放被删除结点的内存
free(q);
}
//打印链表
void print(listNode * head);
void print(listNode * head)
{
listNode *p;
p=head->next;
//如果p存在,则循环
while(p)
{
printf("%s,%d",p->name,p->age);
//指向p的下一个结点
p=p->next;
}
}
单链表的最大缺点就是:每次进行操作都要从头结点开始,只能向后查找,为了解决单链表的缺陷,数据结构中加入了双链表的概念,本博客将在最近对双链表进行剖析;
以上代码及观点如果存在错误,还望指正。