zoukankan      html  css  js  c++  java
  • 链表解说和基本操作练习附代码

    下面都是单链表的基本操作,我都写了一遍,链表时间长不写一定会陌生,留给自己以后忘了看一眼,顺便给想学习链表的同学一点提示吧

    首先先写头文件head.h,这里都是我定义好的函数分别有

    这里的全部样例都是有头结点的链表。都是单链表操作     

    1)头插发建表 2)尾插法建表 3)打印链表 4)对链表赋值的时候进行插入排序 5)将链表翻转 6)找到链表倒数第n个元素 7)将两个链表连在一起 8)使单链表变成环链表

    9)推断链表是否有环 10)将现有的链表排序进行插入排序(与4)不同,4)是在建立链表的时候进行排序。) 11)删除链表反复元素 12)推断链表是否有交点,并输出 13)使两个链表有交点

    #ifndef _LINK_H_
    #define _LINK_H_
    #include<iostream>
    #include<stdio.h>
    #include<time.h>
    #define out
    using namespace std;
    struct node_stu{
    	int num;
    	node_stu *next;
    };
    void link_init_tail(node_stu **head,int size);
    void link_init_head(node_stu **head,int size);
    void print_link(node_stu *head);
    void link_init_sort_insert(node_stu **head,int size);
    void turn_link(node_stu **head);
    int find_back_num(node_stu *head,int n);
    int find_back_num(node_stu *head);
    void unite_links(node_stu **head1,node_stu **head2);
    void make_link_into_circle(node_stu **head);
    int judge_circle(node_stu *head);
    void sort_link(node_stu **head);
    void delete_repetition(node_stu** head);
    int count_intersection(node_stu *head1,node_stu *head2,node_stu** node_intersection);
    void make_intersection_link(node_stu** head1,node_stu** head2,int ,int );
    #endif

    1)头插发建表

    #include"head.h"
    void link_init_head(node_stu **head,int size){
    	*head=(node_stu*)calloc(1,sizeof(node_stu));
    	node_stu *p=*head;
    	p->next=NULL;
    	for(int i=0;i<size;i++){
    		node_stu *temp=(node_stu*)calloc(1,sizeof(node_stu));
    		temp->num=rand()%100;;
    		temp->next=p->next;
    		p->next=temp;
    	}
    }
    

    2)尾插法建表

    #include"head.h"
    void link_init(node_stu **head,int size){
    	node_stu *p;
    	*head=(node_stu *)calloc(1,sizeof(node_stu));
    	p=*head;
    	p->next=NULL;
    	for(int i=0;i<size;i++){
    		p->next=(node_stu *)calloc(1,sizeof(node_stu));
    		p=p->next;
    		p->num=rand()%100;
    		p->next=NULL;
    	}
    }
    
     
     
    3)打印链表
     
    #include"head.h"
    void print_link(node_stu* head){
    	while(head->next!=NULL){
    		head=head->next;
    		cout<<head->num<<" ";
    	}
    	cout<<endl;
    }
     
    4)对链表赋值的时候进行插入排序
     
     
    <pre class="cpp" name="code">#include"head.h"
    void link_init_sort_insert(node_stu **head,int size){
    	*head=(node_stu*)calloc(1,sizeof(node_stu));//定义头指针
    	node_stu *p=*head,*pre=*head;//定义指针p和前指针pre
    	(*head)->next=NULL;//初始化头指针
    	(*head)->num=-1;
    	for(int i=0;i<size;i++){
    		p=*head;
    		node_stu *temp=(node_stu*)calloc(1,sizeof(node_stu));
    		temp->num=rand()%100;//定义节点而且赋予随机数
    		cout<<temp->num<<" ";
    		temp->next=NULL;
    		pre=p;
    		int flag_mid=0;//标记在中间进行插入
    		while(p->next!=NULL){
    			pre=p;
    			p=p->next;//p在前面探路。pre紧随其后,然后temp找到合适位置就插在pre和p适当的位置
    			if((temp->num)>=(pre->num) && (temp->num)<=(p->num)){
    				flag_mid=1;
    				break;
    			}
    		}
    		if(flag_mid!=1)//在头插入或者在未插入
    			p->next=temp;
    		else {		
    			pre->next=temp;//在pre和p中间插入
    			temp->next=p;
    		}
    	}
    }

    5)将链表翻转
    
    
    #include"head.h"
    void turn_link(node_stu **head){
    //	node_stu *newhead=(node_stu*)calloc(1,sizeof(node_stu));
    //	newhead->next=NULL;将链表逆序
    	node_stu *p=*head;
    	p=p->next;
    	(*head)->next=NULL;
    	while(p!=0){
    		node_stu *temp=(node_stu*)calloc(1,sizeof(node_stu));//定义一个暂时结构体节点
    		temp=p;
    		p=p->next;
    		temp->next=NULL;//从链表头部中截取一个节点
    		temp->next=(*head)->next;//将这个节点(头插法)插到表头中
    		(*head)->next=temp;
    	}
    }
    
    6)找到链表第n个元素
     
     
    #include"head.h"
    int find_back_num(node_stu *head,int n){
    	node_stu *pre;
    	pre=head;
    //	至楼顶两个指针,一个head一个pre,中间间隔n
    	n--;
    	while(n--)
    		pre=pre->next;
    	while(pre->next!=NULL){//当pre到头的时候head就是倒数第n个
    		pre=pre->next;
    		head=head->next;
    	}
    	return head->num;
    }
    
     
    7)将两个链表连接在一起
     
    <pre class="cpp" name="code">#include"head.h"
    void unite_links(node_stu **head1,node_stu **head2){//将两个链表结合
    	node_stu *p;
    	p=(*head1);
    	while(p->next!=NULL)
    		p=p->next;
    	p->next=(*head2)->next;
    //	delete (node_stu*) head2;
    }
    		

    8)将链表变成循环链表
    
    
    <pre class="cpp" name="code">#include"head.h"
    void make_link_into_circle(node_stu **head){//是head链表变成有环的
    	node_stu *p;
    	p=(*head);
    	while(p->next!=NULL)
    		p=p->next;
    	p->next=(*head)->next;
    }

    9)推断链表是否有环
    
    
    <pre class="cpp" name="code">#include"head.h"
    int judge_circle(node_stu *head){
    	node_stu *p;
    	p=head->next;
    	head=head->next;
    	while(head!=NULL){
    		head=head->next;
    		if(head==p)
    			return 1;
    	}
    	return 0;
    }
    

    10)将链表进行插入排序
    
    
    主要思想是,将链表的一个点摘下来,在用原链表的头作为新的头在进行插入排序
    <pre class="cpp" name="code">#include"head.h"
    void sort_link(node_stu **head){//对链表进行排序
    	node_stu *pre,*find_p,*original_p,*sort_p;
    //	sort_p=(*head)->next->next;
    	original_p=(*head)->next;//记录原始字符串的位置
    	(*head)->next=NULL;//将头结点next赋NULL,这个作为一个新的字符串開始
    	find_p=(*head);//找到字节在新的字符串中应该放的位置。与pre相相应,find_p在左,pre在右
    	while(original_p!=NULL){//
    		sort_p=original_p;//须要增加新的排序字符串的节点
    		original_p=original_p->next;//记录原始字符串的位置向后移
    		sort_p->next=NULL;//将sort—p隔离出来
    		find_p=(*head);//每次都从新的头结点開始找
    		int flag_mid=0;//标记在中间进行插入
    		while(find_p->next!=NULL){//
    			pre=find_p;//
    			find_p=find_p->next;//pre 与find_p 一前一后。寻找插入值
    			if((sort_p->num)>=(pre->num) && (sort_p->num)<=(find_p->num)){//
    				flag_mid=1;//
    				break;
    			}
    		}
    		if(flag_mid!=1)//在头插入或者在未插入
    			find_p->next=sort_p;
    		else {		
    			pre->next=sort_p;//在中间插入
    			sort_p->next=find_p;
    		}
    		
    	}
    	
    }
    
    11)删除链表中反复元素
     
    <pre class="cpp" name="code">#include"head.h"
    void delete_repetition(node_stu** head){
    	node_stu *end,*first,*temp;
    	end=(*head)->next;
    	first=end->next;
    	while(first!=NULL){
    		if(end->num==first->num){//遇到同样的就删
    			temp=end->next;
    			end->next=first->next;	
    			first=first->next;
    			delete (node_stu *) temp;
    		}
    		first=first->next;
    		end=end->next;
    	}
    }
    			 


     

    12)推断两个链表是否有交点,并输出交点

    
    
     
    #include"head.h"
    int count_intersection(node_stu *head1,node_stu *head2,node_stu** node_intersection){
    	int len1=0,len2=0,len;
    	node_stu *p1,*p2;
    	p1=head1;
    	p2=head2;
    	while(p1->next!=NULL){//计算p1有多长
    		len1++;
    		p1=p1->next;
    	}
    	while(p2->next!=NULL){//计算p2有多长
    		len2++;
    		p2=p2->next;
    	}
    	len=len1>len2?len2:len1;
    	p1=head1;
    	p2=head2;
    
    	while(len--)//取最小值然后找到p1倒数len个节点是什么
    		p1=p1->next;
    	while(p1->next!=NULL){
    		p1=p1->next;
    		head1=head1->next;
    	}
    	len=len1>len2?

    len2:len1; while(len--)//取最小值然后找到p2倒数len个节点是什么 p2=p2->next; while(p2->next!=NULL){ p2=p2->next; head2=head2->next; } while(head1->next!=NULL){//在同一时候p1。p2为倒数len时,開始向后比較,看是否有交点 head1=head1->next; head2=head2->next; if(head1==head2){ *node_intersection=head1;//返回交点 return 1; } } return 0; }

     
    13)使两个链表相交
    
     
    #include"head.h"
    void make_intersection_link(node_stu** head1,node_stu** head2,int n,int m){//m新生成的。n是head1链表,输入的n是想让第n个节点为head1的交点。让m为head2的交点
    	node_stu *p,*p1;
    	*head2=(node_stu *)calloc(1,sizeof(node_stu));
    	p=*head2;
    	p->next=NULL;
    	for(int i=0;i<m;i++){
    		p->next=(node_stu *)calloc(1,sizeof(node_stu));
    		p=p->next;
    		p->num=rand()%100;
    		p->next=NULL;
    	}
    	p1=*head1;//这里链表head1是之前就建好的
    	while(n--)//将head1自增到n,
    		p1=p1->next;
    	p->next=p1;//然后与新生成的head2的第m个位置指向head1的第n个位置
    }
    
    
     
    我写的主函数用来測试各个函数
    <pre class="cpp" name="code">#include"head.h"
    int main(int argc,char *argv[]){
    	srand(time(NULL));
    	node_stu *head=NULL;
    	node_stu *head2=NULL;
    	node_stu *head3=NULL;
    	node_stu *node_intersection=NULL;
    	int intersection_a,intersection_b;
    	int size,n;
    	while(~scanf("%d",&size)){
    //头插发
    //		link_init_tail(&head,size);
    //尾插法
    //		link_init_head(&head,size);
    		printf("插入后排序:
    ");
    		link_init_sort_insert(&head,size);//插入是排序
    		cout<<endl;
    		print_link(head);//打印字符串
    		printf("链表翻转:
    ");
    		turn_link(&head);//链表翻转
    		print_link(head);//
    
    		printf("输出去倒数第几个元素:");
    		while(scanf("%d",&n),(n>size || n<=0))
    			printf("输入的数范围不正确。请又一次输入
    ");//,
    		printf("%d
    ",find_back_num(head,n));//		
    		printf("输出链表中间元素:
    ");
    		cout<<find_back_num(head)<<endl;//
    
    		printf("输出两个字符串:
    ");
    		print_link(head);
    		link_init_head(&head2,size);///
    		print_link(head2);
    		printf("合并之后:
    ");
    		unite_links(&head,&head2);//
    		print_link(head);
    /***
    //		printf("推断链表是否有环
    ");
    //		print_link(head2);
    //		make_link_into_circle(&head2);//是链表编程有环链表
    //		if(judge_circle(head2))
    //			printf("有环
    ");
    //		else
    //			printf("无环
    ");
    */
    
    /*****/
    		printf("将链表排序
    ");
    		sort_link(&head);
    		print_link(head);
    
    		/**/
    		printf("删除反复元素
    ");
    		delete_repetition(&head);/////////////////////////
    		print_link(head);
    
    
    		printf("推断两个链表是否有环,假设有输出环
    ");
    
    		printf("制造两个有交点的链表。输入想让head链表第几个节点成为交点。同一时候新生成的链表第几个成为交点;");
    		
    		scanf("%d %d",&intersection_a,&intersection_b);
    		make_intersection_link(&head,&head2,intersection_a,intersection_b);
    //		link_init_head(&head2,size);
    		if(count_intersection(head,head2,&node_intersection)){
    			printf("有
    ");
    			cout<<node_intersection->num<<endl;
    		}
    		else printf("无
    ");
    	}
    	system("pause");
    }

    
    
    
       
    
  • 相关阅读:
    Maven学习总结(八)——使用Maven构建多模块项目
    Maven学习总结(七)——eclipse中使用Maven创建Web项目
    Maven学习总结(六)——Maven与Eclipse整合
    Maven学习总结(五)——聚合与继承
    BBS的登陆——发帖——回帖
    bugfree,CDbConnection 无法开启数据库连线: SQLSTATE[HY000] [2003] Can't connect to MySQL server on '192.168.0.99' (4)
    Mac 中配置Apache
    Mac里安装配置Jdk
    启动mongodb遇到的错:warning: 32-bit servers don't have journaling enabled by deflity
    分享组2015.7.31
  • 原文地址:https://www.cnblogs.com/yxysuanfa/p/6794514.html
Copyright © 2011-2022 走看看