本人在学C语言链表的时候总是找不到合适的基本代码,
现在整理为完整的代码供大伙参考。
以下是带头结点的情况。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
char ISBN[40];
char name[40];
int price;
}Book;
typedef struct LNode{ //定义单链表结点类型
Book data; //每个节点存放一个数据元素
struct LNode *next; //指针指向下一节点
}LNode,*LinkList;
//初始化一个单链表(带头结点)
void InitList(LinkList &L){
L = (LNode *)malloc(sizeof(LNode)); //分配一个头结点
if (L==NULL){ //内存分配失败
printf("内存分配失败!\n");
return;
}
L->next =NULL;
return;
}
//按位查找,返回第i个元素(带头结点)
LNode * GetElem(LinkList L,int i){
if(i<0)
return NULL;
LNode *p; //指针p指向当前扫描到的结点
int j=0; //当前p指向的是第几个结点
p = L; //L指向头结点,头结点是第0个结点(不存数据)
while(p != NULL && j<i){ //循环找到第i个结点
p = p->next;
j++;
}
return p;
}
//按值查找,找到数据域==e的结点
LNode * LocateElem(LinkList L,int e){
LNode *p = L->next; //从第1个结点开始查找数据域为e的结点
while (p != NULL && p->data.price != e)
p = p->next;
return p;
}
//后插操作:在p结点之后插入元素e
bool InsertNextNode(LNode *p,Book &e){
if (p == NULL)
return false;
LNode *s = (LNode *)malloc(sizeof(LNode));
if (s == NULL){ //内存分配失败
printf("内存分配失败!\n");
return false;
}
s->data = e; //用结点s保存数据元素e
s->next = p->next;
p->next = s; //将结点s连到p之后
return true; //插入成功
}
//按位序插入(后插)。在第i个位置插入元素e
bool ListInsert(LinkList &L,int i,Book &e){
if(i<1)
return false;
LNode *p = GetElem(L,i-1); //找到第i-1个结点
return InsertNextNode(p,e);
}
//前插操作1:在p结点之前插入元素e
bool InsertPriorNode1(LNode *p,Book &e){
if (p == NULL)
return false;
LNode *s = (LNode *)malloc(sizeof(LNode));
if (s == NULL){
printf("内存分配失败!\n");
return false;
}
s->next = p->next;
p->next = s; //新结点s练到p之后
s->data = p->data; //将p中元素复制到s中
p->data = e; //p中元素覆盖为e
return true;
}
//前插操作2:在p结点之前插入结点s
bool InsertPriorNode2(LNode *p,LNode *s){
if (p == NULL || s == NULL)
return false;
s->next = p->next;
p->next = s; //s连到p之后
Book temp = p->data; //交换数据域部分
p->data = s->data;
s->data = temp;
return true;
}
//指定删除节点p
bool DeleteNode(LNode *p){
if (p==NULL){
printf("i为无效值。\n");
return false;
}
LNode *q = p->next; //令q指向*p的后续结点
p->data = p->next->data; //和后续结点交换数据域
p->next = q->next; //将*q结点从链中“断开”
free(q);
return true;
}
//按位序删除
bool ListDelete(LinkList &L,int i,Book &e){
if (i<1)
return false;
LNode *p = GetElem(L,i-1); //找到第i-1个结点
if (p == NULL){ //i值不合法
printf("i为无效值。\n");
return false;
}
if (p->next == NULL) //第i-1个结点之后已无其他结点
return false;
LNode *q = p->next; //令q指向被删除结点
e = q->data; //用e返回元素的值
p->next = q->next; //将*q结点从链中“断开”
free(p); //释放结点的存储空间
return true; //删除成功
}
int Length(LinkList L){
int len = 0; //统计表长
LNode *p = L;
while(p->next != NULL){
p = p->next;
len++;
}
return len;
}
void ListShow(LinkList L){
printf("ISBN \t书名 \t单价\n");
int q = Length(L);
int j=0; //当前p指向的是第几个结点
while(L != NULL && j<q){ //循环找到第i个结点
printf("-------------------------------------------------------------\n");
printf("%-15s \t%-17s\t%-10d\n",L->data.ISBN,L->data.name,L->data.price);
L = L->next;
j++;
}
}
void main(){
LinkList L; //声明一个指向单链表的指针
InitList(L); //初始化一个空表
printf("请输入ISBN:\n");
scanf("%s",&L->data.ISBN);
printf("请输入书名:\n");
scanf("%s",&L->data.name);
printf("请输入价格:\n");
scanf("%d",&L->data.price);
ListInsert(L,1,L->data); //这里必须从1开始插入
ListShow(L);
int q = Length(L);
printf("%d \n",q);
}
以下是测试情况