链表课后题p38-39

#include <iostream>
#include <stack>
using namespace std;
 


typedef struct List{
	int data;
	struct List *next;
}Lnode,*LinkList;  

void deleElem01(LinkList &L,int a){ //删除不带头节点的单链表中值为a的节点,(递归法) 
	Lnode *p;
	if(L==NULL)
	return;
	if(L->data==a){//满足节点值为a
		p=L;
		L=L->next;
		free(p);
		deleElem01(L,a);
	}
	else
	{
		deleElem01(L->next,a); 	//不满足走下一个节点 
	}
}

void deleElem02(LinkList &L,int a){ //删除带头节点的单链表中值为a的节点
	Lnode *p=L->next;//后一个节点
	Lnode *pre=L;//前一个节点
	Lnode *q;
	 
	if(L==NULL)
	return;
	while(p!=NULL){
		if(p->data==a){//满足节点值为a
		q=p;
		p=p->next;
		pre->next=p;
		free(q);
		}
		else
		{
				pre=p;
				p=p->next;
		}	
			
		}

}

void RevPrint01(LinkList L){//反向输出单链表 (递归法)
if(L->next!=NULL){ 
		RevPrint01(L->next);//只要不是链表的尾,就往下递归 
	}
	printf("%d",L->data);//到底就开始反向输出 
	
}




typedef struct Stack	//栈的定义 
{
int * base;  //栈空间基址
int * top;  //指向栈顶有效元素的下一个位置
}Stack;


Stack creat_stack()//创建一个栈 
{
Stack s;
s.base = (int *)malloc(sizeof(int) * 100); //分配栈空间
s.top = s.base;//栈顶与栈顶相同 
return s;
}
void push(Stack &s, int val)//入栈操作 
{
if((s.top - s.base) > 100)//如果空间已满 
{
printf("栈满!");
return;
}
else
{
*(s.top) = val;//给栈传值 
s.top ++;	//栈顶上移 
}
}

void RevPrint02(LinkList L){//反向输出单链表 (栈)
	Stack s = creat_stack();  //创建栈
	Lnode *p=L;
    while(p->next!=NULL){ 
	 push(s,p->data);
	 p=p->next; 
	}
	while(s.top!=s.base){	//类似pop操作 
		s.top --;
		int val = *(s.top);
	printf("%d",val);//到底就开始反向输出 
	

	}

}


void delListMin(LinkList &L){//删除链表中最小元素 
	Lnode *pre=L,*p=pre->next;//将链表的头节点给pre,第一个元素节点给p 
	Lnode *minp=p,*minpre=pre;
	while(p!=NULL){
		if(p->data<minp->data){
			minp=p;
			minpre=pre;//确定最小节点的位置,和前驱 
		}
			pre=p;
			p=p->next; 	//继续扫描 
	} 
	minpre->next=minp->next;//扫描结束。删除最小元素 
	free(minp); 
} 


void reverList(LinkList &L){//带头节点的单链表就地逆置 
	Lnode *p,*r;//p为工作指针。r为P的后继 
	p=L->next;//p承接第一个元素 
	L->next=NULL;//表头赋空 
	while(p!=NULL){ 
		r=p->next;
		p->next=L->next; 
		L->next=p;
		p=r; 
		
	}
}
List Reverse( LinkList &L )//优快云单链表逆转 
{
	//定义两个空节点p,q
	Lnode *p=NULL;
	Lnode *q=NULL;
	//循环节点
	Lnode *l=L;
	while(l!=NULL)
	{
		q=l;//L相当于头节点,先把头给q
		l=l->next;//L指向他的下一个节点
		q->next=p;
		//第一次循环p节点为空
		//当不是第一次循环,p节点是前一个节点,q节点是后一个节点
		//q->next=p完成前节点指向后节点的操作
		p=q;//p指向q节点的位置
	}
	l=q;
}
void SortList(LinkList &L){//给带头节点的链表排序 (10/8 看不懂) 
	Lnode *p=L->next,*pre;
	Lnode *r=p->next;//R是P的后继节点,以保证不断链 
	p->next=NULL;
	p=r;
	while(p!=NULL){
		r=p->next;//保存p的后继节点 
		pre=L;
		while(pre->next!=NULL&&pre->next->data<p->data){
			pre=pre->next;
			p->next=pre->next;
			pre->next=p;
			p=r;
		}
		
	}
} 



void delListBet(LinkList &L,int a,int b){//在链表中,删除值介于(a,b)之间的节点 
	Lnode *p=L->next,*pre=L;
	while(p!=NULL){
		if(p->data>a&&p->data<b){
			pre->next=p->next;
			p=p->next;
			free(p);
		}
		else
		{
		pre=p;
		p=p->next;
		}
	
	}
} 
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
void findSameLnode(LinkList L1,LinkList L2){//找出两个节点的公共节点
//(公共节点的特征是:从首个公共节点开始往后的节点都相同 两个链表形似Y 
	int len1;//=Length(L1);
	int len2;//=Length(L2);//找链长
	int dis;
	LinkList longlist,shorlist;
	if(len1>len2){
		longlist=L1->next;
		shorlist=L2->next;	
		int dis=len1-len2;//链长差 
	} 
	else{
		longlist=L2->next;
		shorlist=L1->next;	
		dis=len2-len1;//链长差 
	}
	while(dis!=0){//将长链表先消耗前dis个多余项 
		longlist=longlist->next;
		dis--;
	} 
	//从第dis开始两个链表一样长
	//开始一起遍历比较 
} 

void printMin(LinkList &L){//依次输出带头节点的链表中最小的值,并释放该节点 
	while(L->next!=NULL){//循环到就剩一个头节点 
		LinkList pre=L;//用于保存最小的值元素的前一个元素 
		LinkList p=pre->next;//遍历指针 
		while(p->next!=NULL){
			if(p->data<pre->next->data)//比较最小值 
				pre=p; 
			p=p->next;
		}
		printf("%d",pre->next->data);
		Lnode *u=pre->next;//找到最小值元素 
		pre->next=u->next;//链接链表 
		free(u);//释放最小值 
	} 
	free(L);//释放头节点 
} 

void ApartList01 (LinkList &L){//将一个带头节点的单链表分解成两个单链表
//A是L中单数节点,B是L中双数节点 
	LinkList A=(LinkList)malloc(sizeof(Lnode));
	LinkList B=(LinkList)malloc(sizeof(Lnode));//申请连个表头 
	A->next=NULL;
	B->next=NULL;//两个链表赋空 
	Lnode *p=L; 
	Lnode *a=A;//a是A的尾指针 
	Lnode *b=B;//b是B的尾指针
	int i=0;//用于判断单双 
	while(p!=NULL){//p是遍历指针 
		i++; 
		if(i%2==1){
			a->next=p;//单数,A的尾指针下一个是p  
			a=p;//尾指针改为p的位置 
		}
		else
		{
			b->next=p;//双数,B的尾指针下一个是p 
			b=p;//更新尾指针的位置 
		}
		p=p->next;	
	}
	a->next=NULL;
	b->next=NULL;//两个新链表尾指针后为NULL 
}

void DelSortList(LinkList &L){//去除递增有序表中的重复元素 
	Lnode *p=L->next;//P为遍历指针 
	if(p==NULL)
	 return;
	Lnode *q;
	while(p->next!=NULL){
		q=p->next;//q是p的下一个指针 
		if(p->data==q->data){//下一个指针的值与前一个相同 
			p->next=q->next;//p指向下一个的下一个,再比较 
			free(q);//相同值free 
			
		}
		else
		p=p->next;
	} 
} 

void MergeList(LinkList &L1,LinkList &L2){
//将两个递增序列的带头节点的单链表合并成一个递减 序列的单链表 
Lnode *p=L1->next;//L1的首元素 
Lnode *q=L2->next;//L2的首元素 
Lnode *r;
L1->next=NULL;//L1用于存储结果链表 ,L1是表头 
while(p&&q){ 
	if(p->data<=q->data){//采用头插法 
		r=p->next;//先记录p的下一个指针 
		p->next=L1->next;//把结果链表连在p后面
		L1->next=p;// P作为头节点之后的第一个节点
		p=r;//p恢复到当前比较节点 
	}
	else//依旧头插 
	{
		r=q->next;
		q->next=L1->next;
		L1->next=q;
		q=r;
	 } 
}
	if(p)//如果p不为空
		q=p;
	//否则就是q不为空
	//就可以直接对q进行头插 
	//这里对q进行操作是因为P的链表L1用于保存结果
	 
	while(q){// 头插 
		r=q->next;
		q->next=L1->next;
		L1->next=q;
		q=r;
	}
	free(L2); //空表头进行释放 
}

void Union(LinkList &L1,LinkList &L2){
//将两个递增序列的带头节点的单链表求他们的交集,并存放在L1中 
//时间复杂度O(len1+len2),空间复杂度o(1) 
Lnode *p=L1->next;
Lnode *q=L2->next;
Lnode *r;
 L1->next=NUL;//L1用来保存交集数据 
Lnode *l=L1;//l是L1的尾指针 

 while(p&&q){
 	if(p->data==q->data){//两个值相同 
 		l->next=p;//尾插结果链表 
 		l=l->next;//更新结果链表尾指针 
 		
 		r=p;
 		p=p->next;
 		free(r);
 		r=q;
		q=q->next;
		free(r); 
	 }
 	else if(p->data<q->data){//P值小的,直接释放 
 		r=p;
 		p=p->next;
 		free(r);	
	 }
	else{//q值小,直接释放 
		r=q;
 		q=q->next;
 		free(r);
	}
 }
 while(p){//不为空的,直接释放 
 	r=p;
 	p=p->next;
 	free(r);
 }
 while(q){//不为空的,直接释放 
 	r=q;
 	q=q->next;
 	free(r);
 } 
 l->next=NULL;
 free(l);
}
int pattern(LinkList &L1,LinkList &L2) {
	//判断L2是否是L1的子序列 
	Lnode *p=L1;
	Lnode *q=L2;
	Lnode *r=p;//r记录p的开始扫描的位置 
	while(q&&p){
		if(p->data==q->data){//如果值相同就往下扫 
			p=p->next;
			q=q->next;
		}
		else{//否则就从下一个元素开始对比 
			r=r->next;
			p=r;
			q=L1;
		}
	
	} 
	if(q==NULL)
	return 1;
	else
	return 0;
	 
}

int main(int argc, char** argv) {
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值