• 数据结构——从顺序表中删除重复的元素


    问题描述:设计一个算法从顺序表中删除重复的元素,并使剩余元素间的相对次序保持不变。
    例如:原顺序表为{4 2 8 4 2 1 2 1 3 5 2},执行该算法后,顺序表为:{4 2 8 1 3 5}。
    另外,顺序表的初始值通过调用算法
    initRandomize(int *arr, int n, int min, int max)产生。

    关于rand(),srand()相关基础知识参考以下内容:
    https://blog.csdn.net/chikey/article/details/66970397
    一、rand()

    rand()函数用来产生随机数,但是,rand()的内部实现是用线性同余法实现的,是伪随机数,由于周期较长,因此在一定范围内可以看成是随机的。

    rand()会返回一个范围在0到RAND_MAX(32767)之间的伪随机数(整数)。

    在调用rand()函数之前,可以使用srand()函数设置随机数种子,如果没有设置随机数种子,rand()函数在调用时,自动设计随机数种子为1。随机种子相同,每次产生的随机数也会相同。

    rand()函数需要的头文件是:<stdlib.h>

    rand()函数原型:int rand(void);

    使用rand()函数产生1-100以内的随机整数:int number1 = rand() % 100+1;

    二、srand()

    srand()函数需要的头文件仍然是:<stdlib.h>

    srand()函数原型:void srand (usigned int seed);

    srand()用来设置rand()产生随机数时的随机数种子。参数seed是整数,通常可以利用time(0)或geypid(0)的返回值作为seed。

    使用rand()和srand()产生1-100以内的随机整数:

    srand(time(0));
    
    int number1 = rand() % 100+1;
    

    三、使用rand()和srand()产生指定范围内的随机整数的方法

    “模除+加法”的方法

    因为,对于任意数,0<=rand()%(n-m+1)<=n-m

    因此,0+m<=rand()%(n-m+1)+m<=n-m+m

    因此,如要产生[m,n]范围内的随机数num,可用:

    int num=rand()%(n-m+1)+m;

    其中的rand()%(n-m+1)+m算是一个公式,记录一下方便以后查阅。

    比如产生10~30的随机整数:

    srand(time(0));

    int a = rand() % (21)+10;


    作者:chikey
    来源:CSDN
    原文:https://blog.csdn.net/chikey/article/details/66970397

    以下为随机数生成函数:

    #include <time.h>
    void initRandomize(int *arr, int n, int min, int max)
    {
        int i = 0;
        srand(time(0));  	/*设置种子,并生成伪随机序列*/
        for (i = 0; i < n; ++i) {
            arr[i] = rand()% (max - min + 1) + min;  /*得到从[min, max]之间的随机数*/
            //printf("%d ", arr[i]);
        }
        //printf("
    
    ");
    }
    

    以下是完整代码
    包含了四个自定义删除相同数的函数
    基于《数据结构》严蔚敏版

    #include <stdio.h> 
    #include <stdlib.h>
    #define OK 1
    #define ERROR 0
    #define OVERFLOW -1
    #define LIST_INIT_SIZE 100 	
    #define LISTINCREMENT  10 	
    typedef int ElemType;	
    typedef int Status; 
    
    typedef struct 
    {
       ElemType     *elem; 								
       int 			length;		  				
       int 			listsize; 		
    } SqList;
    
    // 算法2.3  初始化 
    Status InitList_Sq(SqList &L) 
    {  
      L.elem = (ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));
      if (!L.elem) exit(OVERFLOW);        // 存储分配失败
      L.length = 0;                  
      L.listsize = LIST_INIT_SIZE;   
      return OK;
    }
    
    // 算法2.4  插入 
    Status ListInsert_Sq(SqList &L, int i, ElemType e) 
    {  
      ElemType *p, *q;
      if (i < 1 || i > L.length+1) 
      {// i的合法值为1≤i≤ListLength_Sq(L)+1
      	return ERROR;  
      }
      
      if (L.length >= L.listsize) {// 当前存储空间已满,增加容量
        ElemType *newbase = (ElemType *)realloc(L.elem,
                      (L.listsize+LISTINCREMENT)*sizeof (ElemType));
        if (!newbase) return ERROR;   								
        L.elem = newbase;             							
        L.listsize += LISTINCREMENT;  							
      } 
      q = &(L.elem[i-1]);   							
      for (p = &(L.elem[L.length-1]); p>=q; --p) 
      	*(p+1) = *p;									                              											
      *q = e;      
      ++L.length;   
      return OK;
    } 
    
    //算法2.5 删除 
    Status ListDelete_Sq(SqList &L,int i, ElemType &e)
    {
    	ElemType *p,*q;
    	if(i<1||i>L.length)  return ERROR;
    	p=L.elem+i-1; //p=&(L.elem[i-1]);
    	e=*p;
    	q=L.elem+L.length-1;//最后一个元素的位置
    	for(++p;p<=q;p++)
    		*(p-1)=*p;
    	--L.length;
    }
    
    //销毁顺序表操作 
    Status DestroyList(SqList &L)
    { 
       free(L.elem);
       L.elem=NULL;
       L.length=0;
       L.listsize=0;
       return OK;
    
    }
    
    #include <time.h>
    void initRandomize(int *arr, int n, int min, int max)
    {
        int i = 0;
        srand(time(0));  			/*设置种子,并生成伪随机序列*/
        for (i = 0; i < n; ++i) {
            arr[i] = rand()% (max - min + 1) + min;  /*得到从[min, max]之间的随机数*/
            //printf("%d ", arr[i]);
        }
        //printf("
    
    ");
    }
    
    void ListPrint(SqList &L)
    {
    	for(int i=1; i<= L.length; i++)
    		printf("%d ", L.elem[i-1]);
    	printf("
    ");
    } 
    
    int listdelete1(SqList *L)  //用这个方法结果是错的,暂时没找到原因 
    {							//原因找到:删除完一个元素后,j++,导致更新到原来删除位置的元素没有判断 
    	int *p,*q;				//解决方法:删除完就不要j++了 ,没有进入删除的再j++ 
    	int i,j;
    	for(i=0;i<L->length;i++)
    	{
    		for(j=i+1;j<L->length;)
    		{
    		if(L->elem[i]==L->elem[j])
    		{ 		
    		     //p=L->elem+j; 
    		    p=&(L->elem[j]);  			
    			//q=L->elem+L->length-1; 
    			q=&L->elem[L->length-1] ; 
    			for(++p;p<=q;++p)
    			*(p-1)=*p;
    			--L->length;
    		}
    		else j++; 
    		}			
    	}
    	return OK;   
    }
    
    
    int listdelete2(SqList *L)  //相比与listdelete1少用了两个指针 ,思路是一样的 
    {
    	int i,j;
    	for(i=0;i<L->length;i++)
    	{
    		for(j=i+1;j<L->length;)
    		{
    		if(L->elem[i]==L->elem[j])
    		{
    			for(int m=j+1;m<L->length;m++)
    			L->elem[m-1]=L->elem[m];
    			L->length--; 
    		}
    		else j++;	
    		}			
    	}
    	return OK;   
    }
    
    void listdelete3(SqList *L)//和之前相比,减少了移动,但开辟了新的空间,也变得繁琐了 
    {
    	int i,j,k=1;
    	int a[50]={L->elem[0]};
    	for(j=1;j<L->length;j++)
    	{
    		int flag=1;
    		for(i=0;i<k;i++)
    		{
    			if(a[i]==L->elem[j])
    			{
    				flag=0;
    				break;
    			}			 
    		}
    		if(flag)
    		{
    			L->elem[k]=L->elem[j];
    			a[k++]=L->elem[j];		
    		}	
    	}
    	L->length=k;
    }
    
    void ListDelete_same(SqList *l)   //和listdelete3比不用另外分配空间 
    {								  //这四个删除算法中的最优解 
        int j=1,i=0,len=1;
        while(j<l->length)
        {
            for(i=0;i<len;++i)//和已经进入的不重复集合的元素进行比较 
            {
                if(l->elem[i]==l->elem[j])
                    break;
        	}
            if(i==len)//意味着上面的for循环是正常结束的,所有没重复,可以进入不重复集合 
                l->elem[len++]=l->elem[j++];
            else
                j++;//说明出现重复元素,j++,判断下一个元素 
        }
        l->length=len;//最后不充分数组的长度就是,进入该数组的个数 
    }
    
    const int N=200;
    int	main()
    {
    	int A[N];
    	SqList	List;	
    	InitList_Sq(List);
    	
    	initRandomize(&A[0],N,1,10); //生成50个1~10的随机数 
    	for(int i=1; i<=N; i++)
    		ListInsert_Sq(List,i,A[i-1]);
    			
    	printf("开始时元素序列为:
    ");
    	ListPrint(List);
    	/* 
    	
    	listdelete1(&List);
        ListPrint(List);
    
        listdelete2(&List);
        ListPrint(List);
        
        listdelete3(&List);
        ListPrint(List);
        
        */
        ListDelete_same(&List);
    	printf("
    删除后的顺序表L为:");    
        ListPrint(List);
    	if(DestroyList(List)) 
    	printf("
    成功释放顺序表L");
    			
        getchar();
    }
    
    
  • 相关阅读:
    [2013-08-19] nohup的使用
    HttpParser 相关链接文章
    CKEditor禁用浏览服务器的功能
    (转载)MySQL删除所有表的外键约束、禁用外键约束
    js Object扩展自定义方法,jQuery抛出 Uncaught TypeError: matchExpr[type].exec is not a function
    Javascript 占位符替换
    Springboot 抛出Failed to determine a suitable driver class异常原因
    jpa CriteriaQueryNo explicit selection and an implicit one could not be determined
    Spring ModelAttribute注解失效原因
    Spring Data Jpa 更新操作
  • 原文地址:https://www.cnblogs.com/vivid-victory/p/10090478.html
Copyright © 2020-2023  润新知