数据结构算法设计题汇总(1)

为了更好地学习数据结构,方便自己复习反思,特建立此分类进行课后习题的总结,通过总结来督促自己学习与反思,提升水平,一步步找出更好的算法。

1.将一元素插入一个有序的顺序表中,使其仍然有序,写出能够实现此算法的代码。

我的思路是将元素先插入表尾,之后再进行插入排序,代码如下:

#include
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define maxsize 20
typedef int status;
typedef int elemtype;

typedef struct
{
    elemtype data[maxsize];
    int length;
}sqlist;

status visit(elemtype c)
{
    printf("%d ",c);

    return OK;
}

status initlist(sqlist *l)
{
    l->length=0;
    return OK;
}

status insertlist(sqlist *l,elemtype e,int i)
{
    int k;
    if(l->length==maxsize)
    return ERROR;
    if(i<1||i>l->length+1)
    return ERROR;
    if(i<=l->length)
    for(k=l->length-1;k>=i-1;k--)
    l->data[k+1]=l->data[k];
    l->data[i-1]=e;
    l->length++;
    return OK;
 }

status listtraverse(sqlist l)
{
    int i;
    for(i=0;ilength;i++)
    {
        visit(l.data[i]);
    }
    putchar('\n');
    return OK;
}

status insertsort(sqlist *l){
    int i,j,temp;
    for(i=1;ilength;i++){
        if(l->data[i]data[i-1]){
            temp=l->data[i];
            for(j=i-1;j>=0&&l->data[j]>temp;j--){
                l->data[j+1]=l->data[j];
            }
            l->data[j+1]=temp;
        }
    }
}

int main(void){
    sqlist L;
    int i=0;
    initlist(&L);
    for(i=0;i<10;i++){
        insertlist(&L,i,i);
    }
    listtraverse(L);
    int insert=5;
    insertlist(&L,insert,L.length+1);
    listtraverse(L);
    insertsort(&L);
    listtraverse(L);
}

2.删除一个顺序表中的重复元素

我的思路是使用i,j两个索引,其中i从0开始,j从i+1开始,遍历整个顺序表,当有两元素相等时,删除其中一个即可。

#include
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define maxsize 20
typedef int status;
typedef int elemtype;

typedef struct
{
    elemtype data[maxsize];
    int length;
}sqlist;

status visit(elemtype c)
{
    printf("%d ",c);

    return OK;
}

status initlist(sqlist *l)
{
    l->length=0;
    return OK;
}

status insertlist(sqlist *l,elemtype e,int i)
{
    int k;
    if(l->length==maxsize)
    return ERROR;
    if(i<1||i>l->length+1)
    return ERROR;
    if(i<=l->length)
    for(k=l->length-1;k>=i-1;k--)
    l->data[k+1]=l->data[k];
    l->data[i-1]=e;
    l->length++;
    return OK;
 }

status listtraverse(sqlist l)
{
    int i;
    for(i=0;ilength;i++)
    {
        visit(l.data[i]);
    }
    putchar('\n');
    return OK;
}

status deleteelem(sqlist *l,elemtype e,int i)
{
    int k;
    if(l->length==0)
    return ERROR;
    if(i<1||i>l->length)
    return ERROR;
    e=l->data[i-1];
    if(ilength)
    {
        for(k=i;klength-1;k++)//只需要让后面的不包括自身的元素向前 
        l->data[k]=l->data[k+1];
    }
    l->length--;
    return OK;
} 

status deletesameelem(sqlist *l){
    int i,j;
    elemtype e;
    for(i=0;ilength;i++){
        for(j=i+1;jlength;j++){
            if(l->data[i]==l->data[j]){
                deleteelem(l,e,j);
            }
        }
    }
}

int main(void){
    sqlist L;
    int i=0;
    initlist(&L);
    for(i=0;i<10;i++){
        insertlist(&L,i,i);
    }
    listtraverse(L);
    int insert=5;
    insertlist(&L,insert,L.length+1);
    listtraverse(L);
    deletesameelem(&L);
    listtraverse(L); 
}

3.删除指定范围内的所有元素

最开始我的思路是遍历表,将所有在指定范围的元素找出来并删除,但在实现过程中出现了一些问题,只删除了奇数项而偶数项依然存在。之后我参考了另一个算法,从反面入手,增加新索引k=0,使不在范围内的元素保存在原顺序表中,同时k++,最后让表长等于k即可,代码如下:

#include
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define maxsize 20
typedef int status;
typedef int elemtype;

typedef struct
{
    elemtype data[maxsize];
    int length;
}sqlist;

status visit(elemtype c)
{
    printf("%d ",c);

    return OK;
}

status initlist(sqlist *l)
{
    l->length=0;
    return OK;
}

status insertlist(sqlist *l,elemtype e,int i)
{
    int k;
    if(l->length==maxsize)
    return ERROR;
    if(i<1||i>l->length+1)
    return ERROR;
    if(i<=l->length)
    for(k=l->length-1;k>=i-1;k--)
    l->data[k+1]=l->data[k];
    l->data[i-1]=e;
    l->length++;
    return OK;
 }

status listtraverse(sqlist l)
{
    int i;
    for(i=0;ilength;i++)
    {
        visit(l.data[i]);
    }
    putchar('\n');
    return OK;
}

status deleteelem(sqlist *l,int i)
{
    int k;
    if(l->length==0)
    return ERROR;
    if(i<1||i>l->length)
    return ERROR;
    if(ilength)
    {
        for(k=i;klength-1;k++)//只需要让后面的不包括自身的元素向前 
        l->data[k]=l->data[k+1];
    }
    l->length--;
    return OK;
} 

status deleteeleminrange(sqlist *l,int x,int y){
    int i=0,k=0;/*这一步一定要将k初始化为0否则会出现整个线性表全为同一数字的情况*/
    for(i=0;ilength;i++){
        if(l->data[i]<x||l->data[i]>y){
            l->data[k++]=l->data[i];
        }
    }
    l->length=k;
}

int main(void){
    sqlist L;
    int i=0,x=0,y=0;
    initlist(&L);
    for(i=0;i<10;i++){
        insertlist(&L,i,i);
    }
    listtraverse(L);
    deleteeleminrange(&L,2,6);
    listtraverse(L);
}

4.给定一个含有数字,字母,其他字符的线性表,要求按照字母,数字,其他字符的顺序进行排序。

对于此题,我的思路是使用ctype.h头文件中的isdigit(),isalpha()函数,对线性表进行遍历,找出其中的数字字母其他字符。之后转存到另一线性表中即可,代码如下:

#include
#include
#include
#define maxsize 20
typedef int status;
typedef char elemtype;
typedef struct sqlist{
    elemtype ch[maxsize];
    int length;
}sqlist;

status initlist(sqlist *l){
    l->length=0;
} 

status createlist(sqlist *l){
    l->ch[0]='a';
    l->length++;
    l->ch[1]=',';
    l->length++;
    l->ch[2]='2';
    l->length++;
}

status visit(elemtype c){
    printf("%c ",c);
}

status traverselist(sqlist l){
    for(int i=0;ilength;i++){
        visit(l.ch[i]);
    }
    printf("\n");
}

elemtype getelem(sqlist *l,int i){
    elemtype e;
    if(l->length==0)
        return 0;
    e=l->ch[i-1];
    return e; 
}

int main(void){
    sqlist l,l2;
    elemtype e;
    int i,k=0;
    initlist(&l);
    initlist(&l2);
    l.ch[0]='a';
    l.length++;
    l.ch[1]=',';
    l.length++;
    l.ch[2]='2';
    l.length++;
    l.ch[3]='f';
    l.length++;
    l.ch[4]='.';
    l.length++;
    l.ch[5]='5';
    l.length++;
    traverselist(l);
    for(i=1;i<=l.length;i++){
        e=getelem(&l,i);
        if(isalpha(e)){
            l2.ch[k++]=e;
            l2.length++;
        }
    }
    for(i=1;ilength+1;i++){
        e=getelem(&l,i);
        if(isdigit(e)){
            l2.ch[k++]=e;
            l2.length++;
        }
    }
    for(i=1;ilength+1;i++){
        e=getelem(&l,i);
        if(!isalpha(e)&&!isdigit(e)){
            l2.ch[k++]=e;
            l2.length++;
        }
    }
    traverselist(l2);
}

5.给定一顺序表,将其对称反转
例如:将{0 1 2 3 4 5 6 7 8 9}反转为{5 6 7 8 9 0 1 2 3 4}

我的思路是:用两个索引i=0,j=m(m为对称轴位置)对表进行遍历,遍历的同时左右进行交换,代码如下:

#include
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define maxsize 20
typedef int status;
typedef int elemtype;

typedef struct
{
    elemtype data[maxsize];
    int length;
}sqlist;

status visit(elemtype c)
{
    printf("%d ",c);
    return OK;
}

status initlist(sqlist *l)
{
    l->length=0;
    return OK;
}

status insertlist(sqlist *l,elemtype e,int i)
{
    int k;
    if(l->length==maxsize)
    return ERROR;
    if(i<1||i>l->length+1)
    return ERROR;
    if(i<=l->length)
    for(k=l->length-1;k>=i-1;k--)
    l->data[k+1]=l->data[k];
    l->data[i-1]=e;
    l->length++;
    return OK;
 }

status listtraverse(sqlist l)
{
    int i;
    for(i=0;ilength;i++)
    {
        visit(l.data[i]);
    }
    putchar('\n');
    return OK;
}

status changeorder(sqlist *l,int m,int n){/*m为对称轴位置,n为表长*/
    int temp;
    int i=0,j=m;
    while(i!=m&&j!=n){
        temp=l->data[i];
        l->data[i]=l->data[j];
        l->data[j]=temp;
        i++;
        j++;
    }
}

int main(void){
    sqlist L,l;
    int i; 
    initlist(&L);
    for(i=0;i<10;i++){
        insertlist(&L,i,L.length+1);
    }
    listtraverse(L);
    changeorder(&L,5,10);
    listtraverse(L);
}

以上是我所想到的一些解决问题的方法,今后还会不断反思,设计出更为高效的算法。

你可能感兴趣的:(数据结构算法设计题,课后习题)