数据结构 顺序表与链表——算法练习(一)

Q1:已知长度为n的L List采用顺序存储结构。设计一个时间复杂度为\mathit{O}\left ( n \right ),空间复杂度为\mathit{O}\left ( 1 \right )的算法,该算法删除List中所有值为x的数据元素。

思路:

两种不可行的方法:1. 每删除一个值为x的元素,就将后面的所有元素前移—— 时间复杂度为\mathit{O}\left ( n^{2} \right )

2. 建立一个新列表,存放list中所有不为x的元素—— 空间复杂度为\mathit{O}\left ( n \right )

A1:

方法一:扫描L,重建L用不为x的元素

//Implement 1
void delete(const E& x){
    int k=0;
    for(int i=0; i<listSize; i++){
        if(listArray[i]!=x){
            listArray[k] = listArray[i];
            k++;
        }
    }
    listSize = k;    //重设顺序表的长度
}

//Implement 2
void delete(SqList *&L ElemType x) {  
    int k=0; 
    for(int i=0; i<L->length; i++){ 
        if (L->data[i]!=x){
            L->data[k]=L->data[i]; 
            k++;
        }
    } 
    L->length = k;    //重设顺序表的长度
}

方法二:用k记录当前值为x的元素的个数,将不为x的元素向前移动k位

//Implement 1
void delete(const E& x){
    int k=0;
    for(int i=0;i<listSize;i++){
        if(listArray[i]==x) 
            k++;
        else 
            listArray[i-k] = listArray[i];
    }
    listSize -= k;        //重置顺序表的长度
}

//Implement 2
void delete(SqList *&LElemType x) {  
    int k=0;
    while (i<L->length) {
        if (L->data[i]==x)
            k++; 
        else
	    L->data[i-k] = L->data[i]; 
            i++; 
        } 
        L->length -= k;    //重置顺序表的长度
}

Q2:设顺序表L有10个整数。设计一个算法,以第一个元素为分界线(基准),将所有小于等于它的元素移到该元素的前面,将所有大于它的元素移到该元素的后面。

A2:

方法一:前后交换:pivot = listArray[0](基准),j从后向前找<=pivot的元素,i从前向后找>pivot的元素

//Implement 1
void move1() {  
    int i=0,j=listSize-1; 
    E& tmp; 
    E& pivot=listArray[0];
    while (i<j) {  
        while (i<j && listArray[j]>pivot) 
            j--;
       while (i<j && listArray[i]<=pivot) 
            i++;	
        if (i<j) {  
            tmp=listArray[i];
            listArray[i]=listArray[j]; 
            listArray[j]=tmp; 
        } 
    } 
    tmp=listArray[0];
    listArray[0]= listArray[j]; 
    listArray[j]=tmp; 
} 

//Implement 2
void move1(SqList *&L) {  
    int i=0. j=L->length-1;  
    ElemType tmp; 
    ElemType pivot=L->data[0];
    while (i<j) {  
        while (i<j && L->data[j]>pivot) 
            j--;
        while (i<j && L->data[i]<=pivot)    
            i++;
        if (i<j) {  
            tmp=L->data[i];
            L->data[i]=L->data[j]; 
            L->data[j]=tmp; 
        } 
    } 
    tmp=L->data[0];
    L->data[0]=L->data[j]; 
    L->data[j]=tmp; 
}

方法二: 前后交换:pivot = listArray[0](基准),j从后向前找<=pivot的元素,前移,i从前向后找>pivot的元素,后移

//Implement 1
void move2() { 
    int i=0, j=listSize-1; 
    ElemType pivot= listArray[0];
    while (i<j) {  
        while (j>i && listArray[j]>pivot) 
            j--;
        listArray[i]= listArray[j];
        while (i<j && listArray[i]<=pivot) 
            i++;
	listArray[j]= listArray[i];
    } 
    listArray[i]=pivot;  
 }

//Implement 2
void move2(SqList *&L) { 
    int i=0, j=L->length-1; 
    ElemType  pivot=L->data[0];
    while (i<j) {  
        while (j>i && L->data[j]>pivot) 
            j--;	
        L->data[i]=L->data[j];
        while (i<j && L->data[i]<=pivot) 
            i++;
        L->data[j]=L->data[i];
        } 
        L->data[i]=pivot; 
 }

Q3:稀疏多项式a和b的加法运算

A3:

创建一个新数组c;

分别从头遍历a和b的每一项:若指数相同,则对应系数相加,若其和不为0,则在c中增加一个新项;若指数不同,则将指数较小的项复制到c中。

一个多项式已遍历完毕时,将另一个的剩余项依次复制到c中即可。

猜你喜欢

转载自blog.csdn.net/qq_42182367/article/details/82730231