• 08、单链表编程考点


    单链表编程考点

    1、将单链表的第一个结点放在单链表的最后一个结点的后面

    /*
    设h是无头结点的单链表,如果线性表h的长度不小于2,则将首元结点删除并插入到表尾
    将单链表的第一个结点放在单链表的最后一个结点的后面
    */
    typedef struct node
    {
    	elementype data;
    	struct node *next;
    }*linklist;
    
    void change(linklist &h)    //linklist &h等价于struct node *&h,这样就可以修改指针h的值;此时不需要return返回已经修改的单链表的值
    {
    	linklist p,q;			//linklist p,q等价于struct node *p、struct node *q;
    	if(h && h->next)		//如果链表中有不少于2个结点
    	{
    		q = h;				//令p指向第1个结点h
    		h = h->next;		//令h指向第2个结点
    		p = h;				//令p指向第2个结点
    		while(p->next)		//第一次循环时,判断第2个结点的指针域是否为空,如果为空则只有两个结点,则不需要找到最后的一个结点,否则一直循环,找到最后一个结点为止
    			p = p->next;	//顺着p开始往下找,一直找到最后一个结点
    		p->next = q;		//将第一个结点接在最后一个结点后面
    		q->next = NULL;		//新的尾结点没有后继,置后继为空
    	}
    }
    /*
    	分析:1、在if判断语句中h为单链表的某一指针指向单链表中的某一个结点
    		  2、q = h;此语句的含义是另外一个指针q与指针h同时指向同一个结点
    		  3、h = h->next;此语句中的h->next所表示的含义是h->next指向单链表中h指针指向的下一个结点,与此同时h指针和h->next指针同时指向该结点
    */
    
    typedef struct node
    {
    	elementype data;
    	struct node *next;
    }*Linklist;
    
    Linklist mynode(LinkList L)		//L是不带头结点的单链表的头指针
    {
    	if(L && L->next)			//如果链表中有不少于2个结点
    	{
    		q = L;					//令p指向第1个结点h
    		L = L->next;			//令h指向第2个结点
    		p = L;					//令p指向第2个结点
    		while(p->next)
    		p = p->next;			//顺着p开始往下找,一直找到最后一个结点
    		p->next = q;			//将第一个结点接在最后一个结点后面
    		q->next = NULL;			//新的尾结点没有后继,置后继为空
    	}
    	return L;
    }
    

    2、实现单链表的删除算法,删除成功返回1,删除失败返回0

    /*实现单链表的删除算法,删除成功返回1,删除失败返回0*/
    typedef struct node
    {
    	elementype data;
    	struct node *next;
    }*LinkList, LNode;
    
    int ListDelete(LinkList L, int i, ElemType *s)        //s是存储将要删除的值,i是将要被删除元素的指定位置
    {
    	LNode *p,*q;								  	  //定义了两个新的指针变量p、q;
    	int j;
    	p = L;											  //p指向L单链表的第一个结点元素
    	j = 0;
    	while((p->next != NULL)&&(j < i-1))				  //j < i-1此处的判断条件是i-1的原因是当最后一次,不满足条件之前,j的值自动增加了一位
    	{
    		p = p->next;								  //而我们进行删除操作的前提是找到被删除结点元素的前驱结点
    		j++;										
    	}
    	if(p->next == NULL || j > i-1)
    		return 0;									//如果if语句成立,将执行return 0;语句,运行过程终止
    	q=p->next;										//否则将q指针指向p->next指针所指的结点,即指向被删除结点元素										
    	*s = q->data;
    	p->next = q->next;								//此语句将指定位置的结点删除,p->next所代表的是被删结点元素的前驱结点的next指针域,而q->next指向被删结点元素的后继结点
    	free(q);										//释放结点占有的存储空间
    		return 1;
    }
    

    3、尾插法建立单链表

    //尾插法建立单链表
    typedef struct node
    {
    	int data;
    	struct node *next;
    }lklist;
    void lklistcreate(lklist *&head ,int n)					//n表示单链表的长度
    {
    	lklist *q;											//定义一个新的结点指针	
    	for(i = 1;i<=n;i++)
    	{							
    		p=(lklist *)malloc(sizeof(lklist));				//创建一个新的结点
    		scanf("%d",&(p->data));							//获取该结点的数值
    		p->next = NULL;
    		if(i==1)
    			head = q = p;								//head = q = p;该语句表示头指针head,新的结点指针q都指向结点p;
    		else
    		{
    			q->next = p;								//注意:定义的新的结点指针q的作用是通过移动该指针的指向,来实现链表的创建,将q结点的next指针域指向最新创建的结点
    			q=p;										//将结点连接以后,再改变q指针的指向,为下一次新结点的创建作好准备
    		}
    	}
    }
    

      

    4、逆转线性单链表,采用是头插法

    //逆转线性单链表,采用是头插法
    typedef struct node					//就地逆置单链表
    {
    	elemtype data;
    	struct node *next;
    }node;
    node *Reverse (node *head)			//head是带头结点的单链表
    {
    	node *p ,*q;
    	p = head->next;					//p指向第一个元素
    	head->next=NULL;				//保留第一个元素,将头结点的指针域置空
    	while(p!=NULL)					//将原链表的元素用头插法插入新的链表中
    	{
    		q=p;						//令q指向链表的当前第一个元素
    		p=p->next;					//p指针后移
    		q->next = head->next;		//在新表中插入结点q
    		head->next = q;
    	}
    	return head;
    }
    

      

    5、在带头结点的单链表L中,删除所有值为x的结点

    //在带头结点的单链表L中,删除所有值为x的结点
    typedef struct LNode
    {
    	Elemtype data;
    	struct LNode *next;
    }LNode, *Linklist;
    void delete(Linklist &L ,ElemType x)
    {
    	LNode *q=L;
    	LNode p=L->next;			//初始化p指向第一个结点,q始终指向p结点的前驱
    	while(p!=NULL)
    	{
    		if(p->data == x)		//若p指针指向当前结点的值等于x
    		{
    			q->next = p->next;
    			free(p);			//删除该结点,并修改p指针
    			p=q->next;			//寻找链表中下一个值为x的结点
    		}
    		else
    		{
    			q=p;
    			p=p->next;			//先使q后移,p向后移动
    		}
    	}
    }
    

      

    6、有序递增序列,删除所有值大于mink且小于maxk的元素

    //有序递增序列,删除所有值大于mink且小于maxk的元素
    typedef struct node					//就地逆置单链表
    {
    	elemtype data;
    	struct node *next;
    }node;
    void Delete_Between(node *head, int mink, int maxk)
    {
    	node *p = head, *q;
    	while(p->next->data <= mink)			//p是最后一个不大于mink的元素
    	   p=p->next;
    	if(p->next)								//如果还有比mink更大的元素
    	{
    		q=p->next;
    		while(q->data<maxk)					//q是第一个不小于maxk的元素
    		q=q->next;							//while循环结束以后,q指向比maxk值还大的结点元素
    		p->next = q;						//此语句是删除所有值大于mink且小于maxk的元素						
    	}
    }
    

      

    7、将带头结点单链表h1和h2合并成升序排列的单链表

    //将带头结点单链表h1和h2合并成升序排列的单链表
    typedef struct L
    {
    	int data;
    	struct L *next;
    }LinkL;
    LinkL *mergeList(LinkL *h1, LinkL *h2)
    {
    	LinkL *h, *Next, *q;
    	h=h1;
    	Next = h;
    	h1=h1->next;								//表h1的第一个结点
    	h2=h2->next;								//表h2的第一个结点
    	while(h1 != NULL && h2 != NULL)				//如果表h1和h2均不为空表
    	{
    		if(h1->data <= h2->data)				//如果h1指针所指向当前结点的值小于h2
    		{										//指针所指向的当前结点的值
    			q=h1;								//则令q暂存h1指针所指向的结点
    			h1=h1->next;						//h1指针向后移动
    		}
    		else										//如果h2指针所指向当前结点的值小于h1
    		{											//指针所指向的当前结点的值
    			q=h2;									//则令q暂存h2指针所指向的结点
    			h2-h2->next;							//h2指针向后移动
    		}
    		Next->next = q;					//将指针p所指向的结点接在Next指针所指的结点后面
    		Next = q;						
    	}
    	if(h1 == NULL)						//如果原h2链表中所有结点已插入但是原h1链表还有结点没插完,则直接把剩余部分接在next指针后面。要是原h1表的所有结点已经全部插完但是h2还有结点没插完,亦是如此
    	Next->next = h2;
    	if(h2 == NULL)
    	Next->next = h1;
    	return h;							//返回新表的指针
    	
    }
    

      

    8、用单链表lc表示集合C,分别将la中的元素取出,再在lb中进行查找,如果在lb中出现,则将其插入到lc中

    //将单链表A分解成一个小于零的单链表和大于零的单链表
    typedef struct node					
    {
    	elemtype data;
    	struct node *next;
    }*LinkList,Linknode;
    void decompose(LinkList La,LinkList Lb,LinkList Lc)
    {
    	Linknode *p;								
    	Lc=(Linknode *)malloc(sizeof(Linknode));	
    	Lc->next = NULL;							//表C的头结点的next域置空
    	p=La->next;									//令p指向表A的第一个元素结点
    	Lb=La;										//令Lb指向表La
    	Lb->next = NULL;							//令表La的next域置空
    	while(p)									//遍历原表A
    	{
    		La=p->next;								//令La暂存p结点的后继指针
    		if(p->data >0)							//如果p结点值大于0,则接在表C后面
    		{
    			p->next=Lc->next;
    			Lc->next = p;
    		}
    		else{									//如果p结点的值小于0,则接在表B后面
    			p->next =Lb->next;
    			Lb->next = p;
    		}
    		p=La;									//令p指向原p所指向的结点的下一个位置
    	}
    }
    

      

    9、将单链表A分解成一个小于零的单链表和大于零的单链表

    //用单链表lc表示集合C,分别将la中的元素取出,再在lb中进行查找,如果在lb中出现,则将其插入到lc中
    typedef struct node					
    {
    	elemtype data;
    	struct node *next;
    }*LinkList,LNode;
    void interaction(LinkList la, LinkList lb, LinkList &lc)
    {
    	LinkList pa ,pb, pc;
    	lc = new LNode();								//生成lc的头结点
    	pc=lc;											//pc永远指向lc的尾结点
    	pa=la->next;									//pa指向la的第一个元素
    	while(pa)
    	{
    		pb=lb->next;								//pa指向lb表的第一个元素
    		while(pb && pb->data != pa->data)
    			pb=pb->next;							//在pb中查找元素,使其值等于pa->data
    			if(pb)									//如果存在这样的元素
    			{
    				pc->next = new LNode();				//生成lc新的尾结点
    				pc = pc->next;						//pc指向新的尾结点
    				pc->data= pa->data;					//将pa->data复制到pc中
    			}
    			pa=pa->next;							//继续比较pa表的下一个结点元素
    	}
    	pc->next =NULL;									//pc为尾结点,pc表比较完成后,置pc后继为空
    }
     
    

      

    10、已知指针hb和ha分别指向两个单链表的头结点,长度为m和n,假设hc指向连接后的链表的头结点

    //已知指针hb和ha分别指向两个单链表的头结点,长度为m和n,假设hc指向连接后的链表的头结点
    typedef struct node					
    {
    	elemtype data;
    	struct node *next;
    }LinkList; 
    void ListConcat(LinkList ha, LinkList hb, LinkList *hc)
    {	
    	LinkList p;                     //把链表hb接在ha后面形成链表hc
    	hc=ha;							//由指针p指向ha的尾元结点
    	while(p->next !=NULL)			//查找原ha表的最后一个结点
    	p=p->next;
    	p->next = hb->next;				//把hb表的第一个元素及其后面元素接在p指针指向的结点后面
    	free(hb);
    }
    

      

    11、删除单链表中重复的元素

    //删除单链表中重复的元素
    typedef struct node					
    {
    	elemtype data;
    	struct node *next;
    }LinkedList ,*LNode; 
    LinkedList DeleteSameElement(LinkedList L)
    {									//L为递增有序的单链表
    	LNode u;
    	LinkedList p, pre;
    	pre = L->next;					//pre指针指向第一个元素结点
    	p= pre->next;					//p指向pre所指结点的后继结点
    	while(p!=NULL)					//如果p指针不为空
    	if(p->data == pre->data)		//p所指结点的值等于pre所指结点的值
    	{
    		u=p;						//用指针u暂存p指针所指向的结点
    		p=p->next;					//p指针后移
    		free(u);					//释放掉u指针所值结点的内存空间
    	}
    	else{							//p和pre两指针所指向的结点值不相等
    		pre = p;					//pre指针后移
    		p = p->next;				//p指针后移
    	}
    }
    

      

    12、交换单链表中指针p所指结点与其后继结点

    //交换单链表中指针p所指结点与其后继结点
    typedef struct node					
    {
    	elemtype data;
    	struct node *next;
    }*LinkList; 
    int exchange(Linklist &head,Linklist p )
    {
    	LinkList q=head->next;				//q指向第一个元素结点
    	LinkList pre=head;					//pre指向头结点
    	while(q!=NULL && q!=p)		        //顺着链表开始查找,一直到q=p
    	{
    		pre=q;
    		q=q->next;
    	}
    	if(p->next ==NULL)			        //退出循环之后,若p无后继,则交换失败
    	return 0;
    	else{
    		q=p->next;
    		pre->next = q;
    		p->next = q->next;
    		q->next = p;
    	}
    	return 1;
    }
    

      

    13、设有一个无序单链表
      1)找出最小值结点
      2)若该数是奇数将与其直接后继结点的数值交换
      3)该数值是偶数将直接后继结点删除

     /*
    设有一个无序单链表
    1、找出最小值结点
    2、若该数是奇数将与其直接后继结点的数值交换
    3、该数值是偶数将直接后继结点删除
    */
    typedef struct node					
    {
    	elemtype data;
    	struct node *next;
    }LinkList; 
    void OutputMin(LinkList L)
    {
    	int temp;
    	LinkList q = L->next;				//p指向第一个元素结点
    	LinkList p= q;
    	while(q)
    	{									//找出最小值结点p,并打印p结点数值
    		if(p->data >q->data)
    			p=q;						//如果发现还有比p指针所指结点的值更小的结点,令p指向该结点,否则q后移
    			q=q->next;
    	}
    	printf("%d",p->data);
    	if(p->next != NULL)					//找到了值最小的结点,若该结点有后继结点
    	{
    		if(p->data % 2 == 1)			//如果该最小值是奇数,则与其后继结点交换
    		{
    			temp=p->data;
    			p->data =p->next->data;
    			p->next->data = temp;
    		}
    		else							//如果该最小值是偶数,则删除其后继结点
    		{
    			q=p->next;
    			p->next = q->next;
    			free(q);
    		}
    	}
    }
    

      

      

  • 相关阅读:
    python学习
    androidandroid中的通过网页链接打开本地app
    Android自定义View之绘制虚线
    Backbone学习记录(3)
    Backbone学习记录(2)
    Backbone学习记录(1)
    网络时间轴中竖线的含义
    控制台笔记
    css hack 笔记
    Fiddler学习笔记
  • 原文地址:https://www.cnblogs.com/wxt19941024/p/7460528.html
Copyright © 2020-2023  润新知