考研数据结构-单链表(线性表)

单链表

带头结点

#include 
#include  //添加malloc函数的头文件
//预定义常量和类型
#define LIST_INIT_SIZE 10 //初始分配量

typedef int ElemType;//取别名 方便改

typedef struct LNode{
     	//定义单链表结点类型
	ElemType data;		//每个结点存放一个数据元素
	struct LNode *next;	//指针指向下一个结点
}LNode,*LinkList;

//初始化一个单链表(带头结点)
bool InitList(LinkList &L){
     
	L=(LNode *)malloc(sizeof(LNode));//分配头结点
	if(L==NULL)//内存不足,分配失败
		return false;
	L->next=NULL;//头结点之后暂时还没有结点
	return true;
}

//正向建立单链表
LinkList List_TailInsert(LinkList &L){
     
	int x;//设ElemType为整型
	L=(LinkList)malloc(sizeof(LNode));//建立头结点
	LNode *s,*r=L;//r为表尾指针
	scanf("%d",&x);//输入结点的值
	while(x!=9999){
     //输入9999表示结束
		s=(LNode *)malloc(sizeof(LNode));
		s->data=x;
		r->next=s;
		r=s;	//r指向新的表尾结点(永远保持r指向最后一个结点)
		scanf("%d",&x);
	}
	r->next=NULL;
	return L;
}
//逆向建立单链表(可以用来逆置)
LinkList List_HeadInsert(LinkList &L){
     
	LNode *s;
	int x;//设ElemType为整型
	L=(LinkList)malloc(sizeof(LNode));//建立头结点
	L->next=NULL;//初始为空链表
	scanf("%d",&x);//输入结点的值
	while(x!=9999){
     //输入9999表示结束
		s=(LNode *)malloc(sizeof(LNode));
		s->data=x;
		s->next=L->next;
		L->next=s;//将新结点插入表中,L为头指针
		scanf("%d",&x);
	}
	return L;
}

//按位查找,返回第i个元素(带头结点)
LNode *GetElem(LinkList L,int i){
     
	if(i<0)
		return NULL;
	LNode *p;//指针p指向当前扫描到的结点
	int j=0;//当前p指向的是第几个结点
	p=L;
	while(p!=NULL&&j<i){
     
		p=p->next;
		j++;
	}
	return p;
}
//按值查找,找到数据域==e的结点
LNode * LocateElem(LinkList L,ElemType e){
     
	LNode *p=L->next;
	//从第1个结点开始查找数据域为e的结点
	while(p!=NULL && p->data!=e){
     
		p=p->next;
	}
	return p;//找到后返回该结点指针,否则返回NULL
}

//指定结点的后插操作(封装的方法)
//后插操作:在p结点之后插入元素e
bool InsertNextNode(LNode *p,ElemType e){
     
	if(p==NULL)
		return false;
	LNode *s=(LNode *)malloc(sizeof(LNode));
	if(s==NULL)//内存分配失败
		return false;
	s->data=e;//用结点s保存数据元素e
	s->next=p->next;
	p->next=s;//将结点s连接到p之后
	return true;
}
//前插操作:在p结点之前插入元素e
bool InsertPriorNode(LNode *p,ElemType e){
     
	if(p==NULL)
		return false;
	LNode *s=(LNode *)malloc(sizeof(LNode));
	if(s==NULL)//内存分配失败
		return false;
	s->next=p->next;
	p->next=s;		//新结点s连到p之后
	s->data=p->data;//将p中元素复制到s中
	p->data=e;		//p中元素覆盖为e
	return true;
}
//在第i个位置插入元素e(带头结点)
bool ListInsert(LinkList &L,int i,ElemType e){
     
	//if(i<1)
	//	return false;
	//LNode *p;//指针p指向当前扫描到的结点
	//int j=0;//当前p指向的是第几个结点
	//p=L;
	//while (p!=NULL && j
	//	p=p->next;
	//	j++;
	//}
	//将上面注释的代码封装后调用
	LNode *p=GetElem(L,i-1);
	return InsertNextNode(p,e);//后插调用
	//return InsertPriorNode(p,e);//头插调用
}

//求表的长度(带头结点)
int Length(LinkList L){
     
	int len=0;
	LNode *p=L;
	while(p->next!=NULL){
     
		p=p->next;
		len++;
	}
	return len;
}
/*
bool Empty(LinkList L){
	if(L==NULL)
		return true;
	else
		return false;
}
*/
//也可以这样,更简洁
bool Empty(LinkList L){
     
	return (L==NULL);
}
//按位序删除(带头结点)
bool ListDelete(LinkList &L,int i,ElemType &e){
     
	//if(i<1)
	//	return false;
	//LNode *p;	//指针指向当前扫描到的结点
	//int j=0;	//当前p指向的是第几个结点
	//p=L;		//L指向头结点,头结点是第0个结点(不存数据)
	//while(p!=NULL && j
	//	p=p->next;
	//	j++;
	//}
	LNode *p=GetElem(L,i-1);
	if(p==NULL)			//i值不合法
		return false;
	if(p->next==NULL)	//第i个结点之后已无其他结点
		return false;
	LNode *q=p->next;	//令q指向被删除的结点
	e=q->data;			//用e返回元素的值
	p->next=q->next;	//将*q结点从链中“断开”
	free(q);			//释放结点的存储空间
	return true;		//删除成功
}
//指定结点的删除(类似前插 有bug)
bool DeleteNode(LNode *p){
     
	if(p==NULL)
		return false;
	LNode *q=p->next;		//令q指向*p的后继结点
	p->data=p->next->data;	//和后继结点交换数据域//p是最后一个结点就空指针
	p->next=q->next;		//将*c结点从链中“断开”
	free(q);
	return true;
}
//打印链表
void PrintList(LinkList L){
     
	L=L->next;
	while(L!=NULL){
     
		printf("%d",L->data);
		L=L->next;
	}
	printf("\n");
}
int main(){
     
	//声明一个指向单链表的指针 此时并没有创建
	LinkList L;
	LinkList search;
	//初始化一个空表
	//InitList(L);
	
	//List_HeadInsert(L);//数据11 12 13 14 15 16 9999
	List_TailInsert(L);

	PrintList(L);
	//查找到链表L的第x个值
	int x=2,y=13;
	search=GetElem(L,x);
	if(search!=NULL){
     
		printf("第%d位值%d\n",x,search->data);
	}
	//查找到链表L中值为y的位置
	search=LocateElem(L,y);
	if(search!=NULL){
     
		printf("值%d位置%d\n",y,search->data);
	}

	//按位置插入
	ListInsert(L,7,17);
	PrintList(L);

	//删除x位置的带回给e
	ElemType e=-1;
	if(ListDelete(L,x,e)){
     
		printf("成功删除%d\n",e);
	}
	PrintList(L);
	//system("pause");//停控制台
	return 0;
}

不带头结点单链表

不全,没写

#include 
#include  //添加malloc函数的头文件
//预定义常量和类型
#define LIST_INIT_SIZE 10 //初始分配量

typedef int ElemType;//取别名 方便改

//单链表
typedef struct LNode{
     	//定义单链表结点类型
	ElemType data;		//每个结点存放一个数据元素
	struct LNode *next;	//指针指向下一个结点
}LNode,*LinkList;

//初始化一个空的单链表(不带头结点)
bool InitList(LinkList &L){
     
	L=NULL;//空表,暂时没任何结点//防止脏数据
	return true;
}
//指定结点的后插操作(封装的方法)
//后插操作:在p结点之后插入元素e
bool InsertNextNode (LNode *p,ElemType e){
     
	if(p=NULL)
		return false;
	LNode *s=(LNode *)malloc(sizeof(LNode));
	if(s==NULL)//内存分配失败
		return false;
	s->data=e;//用结点s保存数据元素e
	s->next=p->next;
	p->next=s;//将结点s连接到p之后
	return true;
}
//不存在第“0”个结点,因此i=1时需要特殊处理
bool ListInsert(LinkList &L,int i,ElemType e){
     
	if(i<1)
		return false;
	if(i==1){
     //插入第1个结点的操作与其他结点操作不同
		LNode *s=(LNode *)malloc(sizeof(LNode));
		s->data=e;
		s->next=L;
		L=s;//头指针指向新结点
		return true;
	}
	LNode *p;//指针p指向当前扫描到的结点
	int j=1;//当前p指向的是第几个结点
	p=L;
	while (p!=NULL && j<i-1){
     //循环找到第i-1个结点
		p=p->next;
		j++;
	}
	return InsertNextNode(p,e);
}

int main(){
     
	//声明一个指向单链表的指针 此时并没有创建
	LinkList L;
	//初始化一个空表
	InitList(L);
	//后续代码
	return 0;
}

你可能感兴趣的