前言
欢迎阅读文章!这里是自己在复习王道数据结构过程中把书上代码编译实现而写的笔记,仅供参考,有误还请指出,谢谢!
单链表
单链表的定义
准备
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INSEASIBLE -1
#define OVERFLOW -2
typedef int ElemType;
单链表中结点的定义
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode,*LinkList;
单链表的基本操作
初始化单链表
//初始化单链表
bool InitList(LinkList &L){
L=NULL;
return TRUE;
}
按序号(位)查找结点
//3.按序号(位)查找结点 ,返回第i个结点指针
LNode *GetElem(LinkList L,int i){
int j=1;
LNode *p=L->next;
if(i<1) return NULL;
if(i==0) return L;
while(p!=NULL&&j<i){
p=p->next;
j++;
}
return p;
}
头插法建立单链表
//1.头插法建立单链表
LinkList List_HeadInsert(LinkList &L){
LNode *s;
int x;
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
scanf("%d",&x);
while(x!=9999){
s=(LNode *)malloc(sizeof(LNode));
s->data=x;
s->next=L->next;
L->next=s;
scanf("%d",&x);
}
return L;
}
尾插法建立单链表
//2.尾插法建立单链表
LinkList List_TailInsert(LinkList &L){
int x;
L=(LinkList)malloc(sizeof(LNode));
LNode *s,*r=L;
scanf("%d",&x);
while(x!=9999){
s=(LNode *)malloc(sizeof(LNode));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
return L;
}
补充:显示链表数据
//补充:显示链表数据
void ListDisp_L(LinkList L)
{
printf("\n当前单链表中的数据是:\n");
LinkList p=L->next;
int i=1;
while(p)
{
printf("单链表的第%d个数是%d\n",i,p->data);
p=p->next;
i++;
}
printf("单链表数据显示完毕!\n");
}
按值查找表结点
这里代码和王道书不一样,用王道书里的代码好像自己搞了好久好像都没有返回值
//4.按值查找表结点 :从第一个结点开始从前往后依次找到某结点数据域的值等于给定值e,返回该结点指针
LNode *LocatElem(LinkList L,ElemType e){
int j=1;
LNode *p=L->next;
while(p!=NULL){
if(p->data==e){
printf("恭喜你找到了,位置是%d\n",j);
printf("要查找的值为%d的结点指针为%p\n",e,p->next);
return p;
}
p=p->next;
j++;
}
printf("没有找到%d",e);
return p;
}
插入结点操作
//5.插入结点操作(将值为x的新结点插入到单链表的第i个位置上)
//在第i个位置插入元素x(带头结点)
bool ListInsert(LinkList &L,int i,ElemType x){
if(i<1) return FALSE;
LNode *p = GetElem(L,i-1);
if(p==NULL) return FALSE;
LNode *s=(LNode *)malloc(sizeof(LNode));
s->data=x;
s->next=p->next;
p->next=s;
return TRUE;
}
拓展:前插操作:在p结点前插入结点s
//拓展:前插操作:在p结点前插入结点s
bool InsertPriorNode(LNode *p,LNode *s){
if(p==NULL || s==NULL) return FALSE;
s->next=p->next;
p->next=s;
ElemType temp=p->data;
p->data=s->data;
s->data=temp;
return TRUE;
}
删除结点操作:按位序删除
//6.删除结点操作:按位序删除
bool ListDelete(LinkList &L,int i,ElemType &e){
if(i<1) return FALSE;
LNode *p = GetElem(L,i-1);
if(p==NULL) return FALSE;
if(p->next==NULL) return FALSE;
LNode *q=p->next;
e=q->data;
p->next=q->next;
printf("删除第%d个数是%d\n",i,e);
free(q) ;
return TRUE;
}
拓展:删除指定结点p
//拓展:删除指定结点p
bool DeleteNode(LNode *p){
if(p==NULL) return FALSE;
LNode *q=p->next;
p->data=p->next->data;
p->next=q->next;
free(q);
return TRUE;
}
求表长
//7.求表长
int Length(LinkList L){
LNode *p = L;
int len = 0;
while(p->next!=NULL){
p=p->next;
len++;
}
return len;
}
总代码
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INSEASIBLE -1
#define OVERFLOW -2
typedef int ElemType;
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode,*LinkList;
//初始化单链表
bool InitList(LinkList &L){
L=NULL;
return TRUE;
}
//3.按序号(位)查找结点 ,返回第i个结点指针 (后面头插法要调用这个函数,所以放前面了)
LNode *GetElem(LinkList L,int i){
int j=1;
LNode *p=L->next;
if(i<1) return NULL;
if(i==0) return L;
while(p!=NULL&&j<i){
p=p->next;
j++;
}
return p;
}
//1.头插法建立单链表
LinkList List_HeadInsert(LinkList &L){
LNode *s;
int x;
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
scanf("%d",&x);
while(x!=9999){
s=(LNode *)malloc(sizeof(LNode));
s->data=x;
s->next=L->next;
L->next=s;
scanf("%d",&x);
}
return L;
}
//2.尾插法建立单链表
LinkList List_TailInsert(LinkList &L){
int x;
L=(LinkList)malloc(sizeof(LNode));
LNode *s,*r=L;
scanf("%d",&x);
while(x!=9999){
s=(LNode *)malloc(sizeof(LNode));
s->data=x;
r->next=s;
r=s;
scanf("%d",&x);
}
r->next=NULL;
return L;
}
//补充:显示链表数据
void ListDisp_L(LinkList L)
{
printf("\n当前单链表中的数据是:\n");
LinkList p=L->next;
int i=1;
while(p)
{
printf("单链表的第%d个数是%d\n",i,p->data);
p=p->next;
i++;
}
printf("单链表数据显示完毕!\n");
}
//4.按值查找表结点 :从第一个结点开始从前往后依次找到某结点数据域的值等于给定值e,返回该结点指针
LNode *LocatElem(LinkList L,ElemType e){
// LNode *p=L->next;
// while(p!=NULL&&p->data!=e)
// {
// p=p->next;
// }
//代码修改起点 :王道的例子好像返回不出结果,这里换了一种方法
int j=1;
LNode *p=L->next;
while(p!=NULL){
if(p->data==e){
printf("恭喜你找到了,位置是%d\n",j);
printf("要查找的值为%d的结点指针为%p\n",e,p->next);
return p;
}
p=p->next;
j++;
}
printf("没有找到%d",e);
//代码修改终点
return p;
}
//5.插入结点操作(将值为x的新结点插入到单链表的第i个位置上)
//在第i个位置插入元素x(带头结点)
bool ListInsert(LinkList &L,int i,ElemType x){
if(i<1) return FALSE;
LNode *p = GetElem(L,i-1);
if(p==NULL) return FALSE;
LNode *s=(LNode *)malloc(sizeof(LNode));
s->data=x;
s->next=p->next;
p->next=s;
return TRUE;
}
//拓展:前插操作:在p结点前插入结点s
bool InsertPriorNode(LNode *p,LNode *s){
if(p==NULL || s==NULL) return FALSE;
s->next=p->next;
p->next=s;
ElemType temp=p->data;
p->data=s->data;
s->data=temp;
return TRUE;
}
//6.删除结点操作:按位序删除
bool ListDelete(LinkList &L,int i,ElemType &e){
if(i<1) return FALSE;
LNode *p = GetElem(L,i-1);
if(p==NULL) return FALSE;
if(p->next==NULL) return FALSE;
LNode *q=p->next;
e=q->data;
p->next=q->next;
printf("删除第%d个数是%d\n",i,e);
free(q) ;
return TRUE;
}
//拓展:删除指定结点p
bool DeleteNode(LNode *p){
if(p==NULL) return FALSE;
LNode *q=p->next;
p->data=p->next->data;
p->next=q->next;
free(q);
return TRUE;
}
//7.求表长
int Length(LinkList L){
LNode *p = L;
int len = 0;
while(p->next!=NULL){
p=p->next;
len++;
}
return len;
}
int main()
{
LinkList L;
InitList(L);//初始化单链表
// //1.头插法 (测试头插法时,把下面主函数尾插法相关代码注释了)
// printf("\n请逆序输入元素,输入完最后一个数后请输入9999表示结束:\n");
// List_HeadInsert(L);
// printf("\n以下为单链表数据\n");
// ListDisp_L(L);
//2.尾插法
printf("\n请顺序输入元素,输入完最后一个数后请输入9999表示结束:\n");
List_TailInsert(L) ;
printf("\n以下为单链表数据\n");
ListDisp_L(L);
printf("\n当前表长为:%d\n",Length(L));
//3.按序号查找结点 ,返回第i个结点指针 或 值
printf("\n即将查找元素结点,请输入元素序号:\n");
int i1;
scanf("%d",&i1);
LNode *p1;
p1=GetElem(L,i1);
if (p1) {
printf("要查找的序号为%d的值为%d\n",i1,p1->data);
printf("要查找的序号为%d的结点的指针为%p\n",i1,p1->next);
} else {
printf("没有找到第%d个元素!\n",i1);
}
//4.按值查找表结点 :从第一个结点开始从前往后依次找到某结点数据域的值等于给定值e,返回该结点指针
printf("\n即将按值查找表结点,请输入要查找的元素值e1:\n");
int e1;
scanf("%d",&e1);
LNode *p2;
p2==LocatElem(L,e1);
//5.插入结点操作(将值为x的新结点插入到单链表的第i个位置上)
printf("\n即将把值为x的新结点插入到单链表的第i个位置上,请依次输入位置i和值x:\n");
int i2,x;
scanf("%d",&i2);
scanf("%d",&x);
ListInsert(L,i2,x);
ListDisp_L(L);
printf("\n当前表长为:%d\n",Length(L));
//6.删除结点操作:按位序删除
printf("\n即将进行删除结点值操作,请依次输入删除位置i和对应值x:\n");
int i3,e2;
scanf("%d",&i3);
scanf("%d",&e2);
ListDelete(L,i3,e2);
ListDisp_L(L);
//7.求表长
printf("\n当前表长为:%d\n",Length(L));
return 0;
}
运行结果
总结
单链表