天勤数据结构编程题

第二章 线性表

设计算法,逆置顺序表中所有元素

void Reverse(Sqlist &L)
{
    int i, j;
    int temp;
    for (int i = 0, j = L.Length; i < j; i++, j++)
    {
        temp = L.data[i];
        L.data[i] = L.data[j];
        L.data[j] = temp;
    }
}

设计算法,顺序表L中删除下标i~j的所有元素

void Del_span(Sqlist &L, int i, int j)
{
    int dalta = j - i + 1; //元素移动的距离
    for (int k = j + 1; k < L.length; k++)
    {
        L.data[k - dalta] = L.data[k];
    }
    L.length = dalta; // 修改表的长度
}

将顺序表L中所有小于表头元素的整数放在前半部分,大于表头元素的整数放在后半部分
注意:这个过程里面的i和j是轮流移动的,即j扫描结束换到i

void Put_x(Sqlist &L)
{
    int temp;
    int i = 0, j = L.length - 1;
    temp = L.data[i];
    while (i < j)
    {
        while (i < j && L.data[j] > temp)
            j--;
        if (i < j)
        {
            L.data[i] = L.data[j];
            i++;
        }
        while (i < j && L.data[i] < temp)
            i++;
        if (i < j)
        {
            L.data[j] = L.data[i];
            j--;
        }
    }
    L.data[i] = temp;
}

有一个递增非空单链表,设计一个算法删除值域重复的结点

void Del_re(LNode *L)
{
    LNode *p = L->next, *q;
    while (p->next != NULL)
    {
        if (p->data == p->next->data)
        {
            q = p->next;
            p->next = q->next;
            free(q);
        }
        else
            p = p->next;
    }
}

删除单链表L(有头结点)中的一个最小值结点 (不太懂)

void Del_min(LNode *L)
{
    LNode *pre = L, *p = pre->next, *minp = p, *minpre = pre;
    while (p != NULL) // 查找最小值结点minp以及期前区结点minpre
    {
        if (p->dara < minp->data)
        {
            minp = p;
            minpre = pre;
        }
        pre = p;
        p = p->next;
    }
    minpre->next = minp->next; //删除*minp结点
    free(minp);
}

线性表,带头结点的单链表L。设计算法将其逆置,要求不能建立新节点,只能通过表中已有节点的重新组合来完成。

void Reverse_1(LNode *L)
{
    LNode *p = L->next, *q;
    L->next = NULL;
    while (p != NULL)
    {
        q = p->next;       // q结点作为辅助结点来记录p的直接后继结点的位置
        p->next = L->next; //将p所指的结点插入新的链表中,我觉得这里p->next = NULL应该也是对的
        L->next = p;       // 因为后继结点已经存入q中,所以p仍然可以找到后继
        p = q;
    }
}

将一个头结点为A的单链表分解成两个单链表A和B,使得A链表只含有原来链表中data域为奇数的结点,B链表为偶结点,且保持原来的相对顺序

void Depart_AB(LNode *A, LNode *&B)
{
    LNode *p, *q, *r;
    B = (LNode *)malloc(sizeof(LNode)); //申请链表B的头结点
    B->next = NULL;                     //申请结点后的常规操作
    r = B;
    p = A;
    while (p->next != NULL)
    {
        if (p->next->data % 2 == 0) // 挑出是偶数的,从链表中取下
        {
            q = p->next;
            p->next = q->next;
            q->next = NULL;
            r->next = q; // 将取下的结点插入到r中
            r = q;
        }
        else
            p = p->next;
    }
}

在N个个位正整数存放在int型数组A[0, … , N-1]中,N为已定义的常量且N≤9,数组N[]的长度为N,另给一个int型变量i,要求只用上述变量(A[0] ~A[N-1]与i,这N+1个整形变量)写一个算法,找出这N个整数中的最小者,并且要求不能破坏数组A[]中的数据。

void findMin(int a[], int &i)     // i用来保存最小值
{
    i = A[0];                     // i先保存存入A[0]的值
    while (i / 10 <= N - 1)       // 取i的十位上的数字作为循环变量,与N-1作比较
    {
        if (i % 10 > A[i / 10])   // 取i的个位上的数字与A[i/10]中的各数值作比较
        {
            i = i - i % 10;       // 如果i的个位上的数字大于A[i/10]中的数字,则将i的个位上的数字换成A[i/10]
            i = i + a[i / 10];
        }
        i = i + 10;               // i的十位上的数字加一,就是对A[]中的下一个数字进行检测
    }
    i = i % 10;                   // 循环结束后,i的个位上的数字保存了A[]中的最小值,将i更新为i的个位上的数字
}

逆序打印单链表中的数据局,假设指针指向了单链表的开始结点

void reprint(LNode *L)
{
    if(L != NULL)
    {
        reprint(L->next);
        cout << L->data << " "; 
    }
}

设有两个有序链表表示的集合A和B,判断他们是否相等

void isEqual(LNode *A, LNode *B)
{
    LNode *p = A->next;
    LNode *q = B->next;
    while (p != NULL && q != NULL)
    {
        if(p->data == q->data)
        {
            p = p->next;
            q = q->next;
        }
        else 
            return 0;
    }
    if(p != NULL || q != NULL) // 判断A、B两个序列长度是否相等
        return 0;
    else 
        return 1;
}

键盘输入n个英文字幕,请编程用输入数据建立一个单链表,并要求将字母不重复存入链表

void createLinkSameElem(LNode *head)
{
    head = (LNode*)malloc(sizeof(LNode));
    head->next = NULL;
    LNode *p;
    int n;
    char ch;
    scanf("%d", n); 
    for (int i = 0; i < n; i++)
    {
        scanf("%s", ch);
        p = head->next;
        while (p != NULL)
        {
            if(p->data == ch)
                break;
            p = p->next;
        }
        if(p == NULL)
        {
            p = (LNode*)malloc(sizeof(LNode));
            p->data = ch;
            p->next = head->next;
            head->next = p;
        }
    }
}

第三章 栈和队列

假设以带头结点的循环链表表示队列,并且只设一个指针指向对为节点,但不设头指针,请写出相应的入队和出队算法。

// 入队
void enQueue(LNode *&rear, int x)
{
    LNode *s = (LNode*)malloc(sizeof(LNode)); // 申请结点空间
    s->data = x;
    s->next = rear->next; //将s结点插入队尾
    rear->next = s;
    rear = s; //rear指向新队尾
}
// 出队
int deQueue(LNode *&rear, int &x)
{
    LNode *s;
    if(rear->next == rear)
        return 0;
    else
    {
        s = rear->next->next; // s指向开始结点
        rear->next->next = s->next; // 队头元素出队
        x = s->data;
        if(s == rear)            // 如果元素出队后队列为空
            rear = rear->next;   // 将rear指向头结点
        free(s);    // 释放队结点空间
        return 1;
    }
}

如果允许在循环队列地两端都可以进行插入和删除操作,要求:写出循环队列的类型定义;分别写出从队尾删除和从队头插入的算法。

// 结构体定义
typedef struct
{
    int data[maxSize];
    int front, rear;
}cysqueue;
// 出队算法(队尾删除)
int deQueue(cycqueue &Q, int &x)
{
    if(Q.front == Q.rear) // 判断队是否为空
        return 0;
    else
    {
        x = Q.data[Q.rear];
        Q.rear = (Q.rear - 1 + maxSize) % maxSize; // 修改队尾指针
        return 1;
    }
}

// 入队算法(队头插入)
int enQueue(cycqueue &Q, int x)
{
    if(Q.rear == (Q.front - 1 + maxSize) % maxSize) // 判断队是否为满
        return 0;
    else
    {
        Q.data[Q.front] = x; 
        Q.front = (Q.front - 1 + maxSize) % maxSize; // 修改队头指针
        return 1;
    }
}

将一个非负的十进制整数N转换为一个二进制数

int BaseTrans(int N)
{
    int i, result = 0;
    int stack[maxSize], top = -1;
    while (N != 0)
    {
        i = N % 2;
        N = N / 2;
        stack[++top] = i;
    }
    while (top != -1)
    {
        i = stack[top];
        --top;
        result = result*10 + i;
    }
    return result;    
}

w

int bracketCheck(char f[])
{
    stack S; char ch;         // 定义一个栈
    char* p = f;
    while (*p != '\0')        // 顺序扫描串中的每一个字符
    {
        if(*p == 39)
        {
            ++p;              // 跳过第一个单引号
            while (*p != 39)
                ++p;
            ++p;              // 跳过最后一个单引号
        }
        else if(*p == 34)     // 双引号内的字符不参与配对比较
        {
            ++p;
            while (*p != 34)  // 跳过第一个双引号
                ++p;
            ++p;              // 跳过最后一个双引号
        }
        else
        {
            switch (*p)
            {
            case '{':
            case '[':
            case '(': push(A, *p);
                // 出现左括号,进栈
                break;
            case '}': getTop(S, ch);
                if(ch == '{')
                    pop(S, ch);      // 栈顶的左花括号出栈
                else
                    return 0;
                break;
            case ']': getTop(S, ch);
                if(ch == '[')        // 栈顶的左方括号出栈
                    pop(S, ch);
                else
                    return 0;
                break;
            case ')': getTop(S, ch);
                if(ch == '(')        // 栈顶的左圆括号出栈
                    pop(S, ch);
                else
                    return 0;
            }
            ++p;
        }
    }
    if(isEmpty(S))
        return 1;
    else
        return 0;
}

设计一个递归算法,求n个不同字符的所有全排序列

void perm(char str[], int k, int n)
{
    int i, j;
    char temp;
    if(k==0)
    {
        for (j = 0; j <= n-1; ++j)
            printf("%c", str[j]);    
    }
    else
    {
        for (i = 0; i <= k; ++i)
        {
            temp = str[k];
            str[k] = str[i];
            str[i] = temp;
            perm(str, k-1, n);
            temp = str[i];
            str[i] = str[k];
            str[k] = temp;
        }    
    }
}

第四章 串

将串str中所有值为ch1的字符转换成ch2的字符,如果str为空串,或者串中不含值为ch1的字符,则什么都不做。

void replace(Str &str, char ch1, char ch2)
{
    for (int i = 0; i < str.Length; i++)
    {
        if (str.ch[i] == ch1)
            str.ch[i] = ch2;
    }
}

实现串str的逆转函数,如果str为空串,则什么都不做

void swap(char& ch1, char& ch2)
{
    char temp = ch1;
    ch1 = ch2;
    ch2 = temp;
}
void reverse(Str& str)
{
    int i = 0;
    int j = str.Length - 1;
    while (i < j)
    {
        swap(str.ch[i], str.ch[j]);
        ++i;
        --j;
    } 
}

删除str中值为ch的所有字符,如果str为空串或者串中不含值为ch的字符,则什么都不做

typedef stuct
{
    char ch[maxSize];
    int length;
}Str;
void delCh(Str &str, char ch)
{
    if (str.length != 0)
    {
        for (int i = 0; i < str.length;)
        {
            if (str.ch[i] == ch)
            {
                for (int j = i; j < str.length - 1; ++j)
                    str.ch[j] = str.ch[j + 1];
                --str.length;
            }
            else
                ++i;
        }
        str.ch[str.length] = '\0';
    }
}

从串str中的pos位置起,求出与substr串匹配的子串的位置,如果str为空串,或者串中不含与substr匹配的子串,则返回-1做标记

int KMP(Str str, Str substr, int pos)
{
    int i = pos, j = 1;
    while (i <= str.length && j <= substr.length)
    {
        if(j == 0 || str.ch[i] == substr.ch[j])
        {
            ++i;
            ++j;
        }
        else
            j = next;
    }
    if(j > substr.length)
        return i - substr.length;
    else 
        return -;   
}

采用定长顺序存储表示串,编写一个函数,删除从下表为i的字符开始的j个字符,如果i后面的字符串不足j个,有几个删几个

算法思想:从下标为i+j个字符开始,将所有的字符向前移动j个单位,然后将字符串进行调整。

void delIJ(Str &str, int i, int j)
{
    if (i < str.length && i >= 0 && j >= 0)
    {
        for (int k = i + j; k < str.length; ++k)
        {
            str.ch[k - j] = str.ch[k];
            str.length -= (str.length - i < j ? str.length - i : j);
            // 调整字符串长度,注意要求
            str.ch[str.length] = '\0';
        }
    }
}

采用顺序存储方式存储串,编写一个函数,将串str1中的下标i到下标j之间的字符用str2替换

算法思想:取str1中0到i-1位置上的子串str11,取str1中j到串尾的子串str12,最后连接str11、str2、str12

这道题我需要冷静一下,真的需要这么复杂吗?

计算一个子串在一个主串中出现的次数,如果该子串不出现,则返回0。不考虑子串重叠

int index(Str str, Str substr)
{
    int i = 1, j = 1, k = 1, sum = 0;
    while (i <= str.length)
    {
        if (str.ch[i] == substr.ch[j])
        {
            ++i;
            ++j;
        }
        else
        {
            j = 1;
            i = ++k; // 匹配失败,i从主串下一位置开始,k中记录了上一次的起始位置
        }
        if (j > substr.length)
        {
            j = 1;
            ++sum;
        }
    }
    return sum;
}

构造串的链表结点数据结构(每个节点内存储一个字符),编写函数,找出串str1中第一个不在str2中出现的字符

typedef struct SNode
{
    char data;
    struct SNode *next;
}SNode;

char findfirst(SNode* str1, SNode*str2)
{
    for (SNode* p = str1; p != NULL; p = p->next)
    {
        bool flag = false;
        for (SNode* q = str1; q != NULL; q = q->next)
        {
            if(p->data == q->data)
            {
                flag = true;
                break;
            }
        }
        if(flag == false)
            return p->data; 
    }
    return '\0';
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_UPS_

感谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值