严老师的书代码会有一些伪代码和使用了c++语法,可能和我们使用的C语言有区别
以下是一个带头节点的单向列表
这里先设置初始条件,C语言有内置的NULL不需要定义,自己需要定义flase和true来返回函数运行的反馈
#include<stdio.h>
#define flase 0
#define true 1
typedef struct LNode {
int data;
struct LNode* next;
} LNode,*LinkList;
这里有些人会不知道LNode 和*Linklist的作用:
先举一个例子:结构体:
struct Books//创建一个结构体
{//结构体内部属性
char title[50];
char author[50];
char subject[100];
int book_id;
} book = {"C 语言", "RUNOOB", "编程语言", 123456};//这里直接用这个结构体创建了一个变量
重命名结构体:使用到了typedef语法:
重命名ttypedef struct book{
}book2222;//这里将该结构体重新命名为book222
说回LNode 和*Linklist的作用:将LNode命名为LNode的变量名和指向LNode的结构团体指针:
初始换链表(带头节点):这里书上是这样传的传int initList( LinkList &L)会报错。
int initList(LinkList L) {//这里传一个结构体指针
L=(LNode*)malloc(sizeof(LNode));//分配一个节点
//判断是否分配成功
if (L==NULL) {
return flase;
}
L->next==NULL;
return true;
}
这是直接传结构体的初始化段代码
在主函数内直接这样声明一个变量:
LNode N ;//此时系统已经开辟出相应的地址
传参时代码如下:
initList2(&N);
int initList2( struct LNode *L) {
//判断是否分配成功
if (L==NULL) {
return flase;
}
L->next==NULL;
return true;
}
因为函数传递进去的参数不使用指针就无法改实际内容
单链表的基本操作:
1、采用头插法建立单链表:
生产一个新节点,将你的数据放入在他的数据域中,然后将新节点插入到链表的标题头:放在头节点之后:
相关代码(头插法):
LinkList List_HeadInsert( LinkList L){
LNode *s;//指向LNode的指针变量
int X;//数据
//新节点的值
L = (LinkList)malloc(sizeof(LNode));
if(L==NULL){
return NULL;
}
L->next = NULL;
printf("输入新节点的内容:\n");
scanf("%d",&X);
while(X!=9999){//输9999结束
s=(LinkList)malloc(sizeof(LNode));//创建新节点
s->data=X;
//printf("%d",L->next);
s->next=L->next;//这里的顺序不能改,否则会指错地方
L->next=s;
scanf("%d",&X);
}
return L;
}
这段函数会返回头指针改动指向后的地址,此时,你还需要再用原来的头指针来接收:
例如:
l2=List_HeadInsert(l2);
否则你使用l2指针会报空指针异常
完整代码:
#include<stdio.h>
#include<stdlib.h>
#define false 0
#define true 1
typedef struct LNode {
int data;
struct LNode* next;
} LNode,*LinkList;
int initList ( LinkList L) {
L = (LinkList)malloc(sizeof(LNode));
// 判断是否分配成功
if (L == NULL) {
return false;
}
L->next = NULL;
return true;
}
int initList2(LNode *L) {
//判断是否分配成功
if (L==NULL) {
return false;
}
L->data=666;
L->next=NULL;
return true;
}
LinkList List_HeadInsert( LinkList L){
LNode *s;//指向LNode的指针变量
int X;//数据
//新节点的值
L = (LinkList)malloc(sizeof(LNode));
if(L==NULL){
return NULL;
}
L->next = NULL;
printf("输入新节点的内容:\n");
scanf("%d",&X);
while(X!=9999){//输9999结束
s=(LinkList)malloc(sizeof(LNode));//创建新节点
s->data=X;
//printf("%d",L->next);
s->next=L->next;
L->next=s;
scanf("%d",&X);
}
return L;
}
//遍历函数:
int show_linklist(LinkList L) {
if(NULL==L){
puts("传入表参数非法");
return -1;
}
if(NULL==L->next){
puts("表为空表 无数据可遍历");
return -1;
}
LinkList q = L->next;
while(NULL!=q){
printf("%d ",q->data);
q = q->next;
}
puts("");
return 0;
}
int main() {
//声明一个链表,
LNode l;
initList2(&l);
printf("Hello world! %d",l.data);
LinkList l2=NULL;//声明一个链表
l2=List_HeadInsert(l2);
if(l2==NULL){
printf("创建链表失败!");
return 0;
}
printf("链表内容如下:头插法,最后输入的最先输出");
show_linklist(l2) ;
return 0;
}
结果如下: