计算机考研_顺序表相关题目

题目来自摘自《22王道考研的数据结构》, 仅用作本人复习参考用

题目1

  1. 从顺序表中删除具有最小值的元素(假设唯一), 并由函数返回被删元素的值.空出的位置由最后一个
    元素填补, 若顺序表为空,则显示出错信息并退出运行.
bool Del_Min(SqList &L, ElemType &value)
{
    if(!L.length) 
    {
        printf("error msg");
        return false;
    }

    int pos = 0;
    int min = L.data[0];
    for(int i = 0; i < L.length; ++i)
        if(min > L.data[i]) pos = i, min = L.data[i];

    value = min;
    if(pos != L.length - 1) L.data[pos] = L.data[L.length - 1];   // 这里的if可以不必进行判断,因为就算是最后一个元素,也会在下面--中被删除.
    L.length--;
    return true;
}

题目2

  1. 设计一个高效的算法,将顺序表L的所有元素逆置,要求算法的空间复杂度为O(1).
void Reverse(sqList &L)
{
    int i = 0, j = L.length - 1;
    while(j > i)
        swap(L.data[i++], L.data[j--]);
}

题目3

  1. 对长度为n的顺序表L,编写一个时间复杂度为O(n),空间复杂度为O(1)的算法,该算法删除线性表中所有值为x的数据元素 */
void del_x_1(Sqlist &L, Elemtype x)                       // 解法1   直接删除法
{
    int k = 0;
    for(int i = 0; i < L.length; ++i)   
        if(L.data[i] != x) L.data[k++] = L.data[i];
    L.length = k;
}


void del_x_2(Sqlist &L, Elemtype x)                      // 解法2    构建法 
{
    int k = 0;
    for(int i = 0; i < L.length; ++i)
        if(L.data[i] != x) L.data[i - k] = L.data[i];
        else ++k;
    L.length = L.length - k;
}

题目4

  1. 从有序顺序表删除其值在给定值s与t之间(要求s < t)的所有元素, 若s或t不合理或顺序表为空,则显示出错信息并退出运行

//注意:这里s和t不一定是顺序表中的元素, 只是给定的这个范围.

bool fun(Sqlist &L, Elemtype s, Elemtype t)
{
    int i, j;
    if(s >= t || !L.length) return false; 
    for(i = 0; i < L.length && L.data[i] < s; ++i);   // 寻找大于等于s的第一个元素. 
    if(i > L.length) return false;
    for(j = i; j < L.length && L.data[j] <= t; ++j);  // 寻找大于t的第一个元素
    while(j < L.length)  L.data[i++] = L.data[j++];
    L.length = i;
    return true;
}

题目5

  1. 从顺序表中删除其值在给定值s与t之间(包含s和t, 要求s<t)的所有元素,若s或t不合理或顺序表为空,则显示错误并退出 */
bool fun(Sqlist &L, Elemtype s, Elemtype t)
{
    if(!L.length || s >= t) return false;

    int k = 0;
    for(int i = 0; i < L.length; ++i)
        if(L.data[i] < s || L.data[i] > t) L.data[k++] = L.data[i];

    L.length = k;
    return true; 
}

题目6

  1. 从有序顺序表中删除所有其值重复的元素, 使表中所有元素均不相同(Lc26)*/
bool fun(Sqlist &L)
{
    if(!L.length) return false;
    int k = 0;

    for(int i = 0; i < L.length; ++i)
        if(!k || L.data[i] != L.data[k - 1]) L.data[k++] = L.data[i];
    L.length = k;
}

题目7

  1. 将两个有序顺序表合并为一个新的有序顺序表, 并由函数返回结果顺序表 */
Sqlist Merge(Sqlist &L1, Sqlist &L2)
{
    Sqlist L;
    int n1 = 0, n2 = 0, l_n = 0;

    while(n1 < L1.length && n2 < L2.length)
    {
        if(L1[n1] < L2[n2]) L[l_n++]  = L1[n1++];
        else  L[l_n++] = L2[n2++];
    }

    while(n1 < L1.length)  L[l_n++] = L1[n1];
    while(n2 < L2.length)  L[l_n++] = L2[n2];
    L.length = l_n;
    return L;
}

题目8

  1. 已知在一维数组A[m+n]中依次存放两个线性表(a1,a2,a3,…,am)和(b1,b2,b3,…,bn).试编写一个函数,将数组中两个顺序表的位置互换, 即将(b1,b2,b3,…,bn)放到(a1,a2,a3,…,am)的前面 .

相关题目: Acwing 77. 翻转单词顺序

void Reverse(int *Arr, int l, int r)
{
    int i = l, j = r;
    while(i < j) swap(Arr[i++], Arr[r--]);
}

void fun(int *arr, int m, int n)
{
    Reverse(arr, 0, m + n - 1);
    Reverse(arr, 0, n - 1);
    Reverse(arr, n, m + n - 1);
}

题目9

  1. 线性表(a1,a2,a3,…,an)中的元素递增有序切按顺序存储于计算机内.要求设计一个算法,完成用最少时间在表中查找数值为x的元素, 若找到,则将其与后继元素位置相交换, 若找不到则将其插入表中并使表中顺序仍然递增有序 */
void fun(Sqlist &L, Elemtype x)
{
    int l = 0, r = L.length - 1;

    if(x > L.data[r])                       // 特判, 若此时比最大一个元素大, 直接插入最后 
    {
        L.data[r + 1] = x;
        L.length++;
        return;
    }

    while(r > l)                             // 二分查找找到第一个大于等于x的元素 
    {
        int mid = (l + r) / 2;
        if(L.data[mid] >= x) r = mid;
        else l = mid + 1;
    }

    if(L.data[l] == x)                        // 找到
    {
        if(l == L.length - 1) return;          // 最后一个元素并无后继 
        swap(L.data[l], L.data[l + 1]);
    }
    else         // 找不到
    {
        for(int i = L.length; i > l; --i)  L.data[i] = L.data[i - 1];
        L.data[l] = x;
        L.length++;
    }
}
//关于二叉树
//二叉树的创建以及递归和非递归遍历
#include <iostream>
#include<iomanip>
#include<stack>
using namespace std;
typedef char TElemtType;

//二叉树的二叉链表存储表示
typedef struct BiTNode
{
    TElemtType data;          //结点数据域
    struct BiTNode *lchild,*rchild;   //左右孩子指针
}BiTNode,*BiTree;

//先序创建二叉树
void CreateBiTree(BiTree &T)
{
    //按先序次序输入二叉树中结点的值(一个字符,创建二叉链表表示树T
   TElemtType ch;
   cin>>ch;
   if(ch=='#') T=NULL;      //递归结束,建空树
   else
   {
       T=new BiTNode;
       T->data=ch;        //生成根结点
       CreateBiTree(T->lchild);   //递归创建左子树
       CreateBiTree(T->rchild);   //递归创建右子树
   }
}
//二叉树的递归和非递归遍历
//先序递归遍历
void PreOrderTraverse(BiTree T)
{
    if(T)
    {
        cout<<setw(4)<<T->data;
        PreOrderTraverse(T->lchild);
        PreOrderTraverse(T->rchild);
    }
}
//先序非递归遍历
void PreOrder(BiTree T)
{
    stack<BiTree>S;
    BiTree p,q;
    p=T;
    q=new BiTNode;
    while(p||!S.empty())
    {
        if(p)          //p非空指针进栈,输出根结点,遍历左子树
        {
            cout<<setw(4)<<p->data;
            S.push(p);
            p=p->lchild;
        }
        else           //p空指针退栈,遍历右子树
        {
            q=S.top();
            S.pop();
            p=q->rchild;
        }
    }
}
//中序递归遍历
void InOrderTraverse(BiTree T)
{
    if(T)
    {
        InOrderTraverse(T->lchild);
        cout<<setw(4)<<T->data;
        InOrderTraverse(T->rchild);
    }
}
//中序非递归遍历
void InOrder(BiTree T)
{
    stack<BiTree>S;
    BiTree p,q;
    p=T;
    q=new BiTNode;
    while(p||!S.empty())
    {
        if(p)      //p非空指针进栈,遍历左子树
        {
            S.push(p);
            p=p->lchild;
        }
        else       //p空指针进栈,访问根节点,遍历右子树
        {
            q=S.top();
            S.pop();
            cout<<setw(4)<<q->data;
            p=q->rchild;
        }
    }
}
//后序递归遍历
void PostOrderTraverse(BiTree T)
{
    if(T)
    {
        PostOrderTraverse(T->lchild);
        PostOrderTraverse(T->rchild);
        cout<<setw(4)<<T->data;
    }
}
//后序非递归遍历
void PostOrder(BiTree T)
{
    if(T==NULL)
        return;
    stack<BiTree>S;
    BiTree pCur,pLastVisit;
    //pCur :当前访问结点 pLastVisit:上次访问结点
    pCur=T;
    pLastVisit=NULL;
    //先把pCur移到左子树最下边
    while(pCur)
    {
        S.push(pCur);
        pCur=pCur->lchild;
    }
    while(!S.empty())
    {
        //走到这里,pCur都是空,并且已经遍历到左子树低底(看成扩充的二叉树,则空,也是某棵树的左孩子)
        pCur=S.top();
        S.pop();
        //一个根结点被访问的前提是 ,该结点无右子树或者右子树已经北方问过
        if(pCur->rchild==NULL||pCur->rchild==pLastVisit)
        {
            cout<<setw(4)<<pCur->data;
            //修改最近被访问的结点
            pLastVisit=pCur;
        }
            /*这里的else可以换成带条件的else if
            else if(pCur->lchild==pLastVisit) 若左子树刚刚被访问过,则需要先进入右子树(根结点需要再次入栈)*/
        else
        {
            //根结点再次入栈
            S.push(pCur);
        //进入右子树,且可以肯定右子树一定不为空
            pCur=pCur->rchild;
            while(pCur)
                {
                    S.push(pCur);
                    pCur=pCur->lchild;
                }
        }
    }
}
//层序遍历
void LevelTraverse(BiTree T)
{
    queue<BiTree>Q;
    Q.push(T);
    while(!Q.empty())
    {
        T=Q.front();
        Q.pop();
        cout<<setw(4)<<T->data;
        if(T->lchild)
            Q.push(T->lchild);
        if(T->rchild)
            Q.push(T->rchild);
    }
}

//非递归程序判断一个二叉树是否是完全二叉树
void IsCompleteTree(TreeNode* root)
{
    queue<TreeNode*>que;
    bool falg;//标志,判断层次遍历之后到该结点是否还能有子节点,true表示之后不能有子节点了
    TreeNode* tmp;
    que.push(root);
    while(!que.empty())
    {
        tmp=que.front();
        que.pop();
        if(flag&&tmp->lChild||tmp->rChild)
            return false;
        if(tmp->lChild)
            que.push(tmp->lChild);
        else
            flag=true;
        if(tmp->rChild)
        {
            if(flag)
                return false;
            else
                que.push(tmp->rChild);
        }
        else
            flag=true;
    }
    return true;
}

//计算叶子结点的个数
int leafCount=0;
void LeafCountBinaryCount(Node *node)
{
    if(node==NULL)
    {
        return ;
    }
    if(node->lChild==NULL&&node->rChild==NULL)
    {
        leafCount++;
    }
    LeafCountBinaryCount(node->lChild);
    LeafCountBinaryCount(node->rChild);
    return ;
}


//计算二叉树高度
int depth(TreeNode* root)
{
    if(!root)
        return 0;
    int left=depth(root->left);
    int right=depth(root->right);
    return max(left,right)+1;
}


//非递归求二叉树的高度


// 交换二叉树根结点的左右子树
TreeNode* InvertTree(TreeNode* root)
{
    if(!root)
        return NULL;
    TreeNode* temp_left=root->left;//保护现场,防止root->left修改后丢失
    root->left=InvertTree(root->right);
    root->right=InvertTree(temp_left);
    return root;
}


// 求解给定关键字在二叉树中所在层数
int searchBST(TreeNode* root,int val)
{
    int num=0;
    while(root)
    {
        num++;
        if(root->val==val)
            return num;
        else if(root->val>val)
        {
            if(!root->left)
                return 0;
            root=root->left;
        }
        else
        {
            if(!root->right)
                return 0;
            root=root->right;
        }
    }
    return 0;
}

// 计算二叉树的最大宽度
int treeWidth(BTNode *root)
{
    if(root==NULL)
        return 0;
    int nLastLevelWidth=0;//记录上一层的宽度
    int nCurLevelWidth=0;//记录当前层的宽度

    queue<BTNode*>Q;
    Q.push(root);//将根结点入队列
    int nWidth=1;//二叉树的宽度
    nLastLevelWidth=1;
    BTNode *pCur=NULL;
    while(!Q.empty())
    {
        while(nLastLevelWidth!=0)//nLastLevelWidth代表上一层的宽度,控制上一层所有结点的孩子进队
        {
            pCur=Q.front();//取出对头元素
            Q.pop();

            if(pCur->left!=NULL)
                Q.push(pCur->left);
            if(pCur->right!=NULL)
                Q.push(pCur->right);
            nLastLevelWidth--;
        }
        nCurLevelWidth=Q.size();//此时也是上一层所有的结点个数
        nWidth=nCurLevelWidth>nWidth?nCurLevelWidth:nWidth;
        nLastLevelWidth=nCurLevelWidth;
    }
    return nWidth;
}

// 将一棵二叉树自下向上,从右往左遍历输出
void InvertLevel(BTNode* root)
{
    stack<BTNode*>S;
    Queue<BTNode*>Q;
    BTNode* pCur;
    if(root!=NULL)
    {
         Q.push(root);  //树不空,根结点进队
         while(!Q.empty())  //队不空
         {
             pCur=Q.front(); //出队,进栈
             Q.pop();
             S.push(pCur);
             if(pCur->lChild)   //子女不空,就入队
                Q.push(pCur->lChild);
             if(pCur->rChild)
                Q.push(pCur->rChild);
         }
         while(!S.empty())
         {
             pCur=S.top();
             S.pop();
             cout<<pCur->data<<'\t';
         }
    }
}


// 计算一棵给定二叉树的所有的双分支结点的个数
int dsonNodes(TreeNode* root)
{
    if(root==NULL)
        return 0;
    else if(root->lChild!=NULL&&root->rChild!=NULL)
        return dsonNodes(root->lChild)+dsonNodes(root->rChild)+1;
    else
        return dsonNodes(root->lChild)+dsonNodes(root->rChild);
}

//将给定的表达式二叉树转换为等价的中缀表达式
// 算法思想:除根结点和叶子结点外,遍历到其他结点时再遍历左子树之前加上括号,遍历完右子树加上括号
void BiTreeExp(TreeNode* root)
{
   BiTreeToExp(root,1);//根的高度为1
}
void BiTreeToExp(TreeNode* root,int depth)
{
    if(root==NULL)
        return;  //空结点返回
    else if(root->left==NULL&&root->right==NULL) //若为叶子结点
        cout<<root->data;       //输出操作数,不加括号
    else
    {
        if(deep>1)    //若又子表达式则加1层括号
            cout<<'(';
        BiTreeToExp(root->left,deep+1);
        cout<<root->data; //输出操作符
        BiTreeToExp(root->right,deep+1);  //若又子表达式则加1层括号
        if(deep>1)
            cout<<')';
    }
}

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值