数据结构复习总结

本文详细介绍了线性表的链表操作,如统计小于特定值的节点、合并循环链表,以及链表的基本操作。此外,涵盖栈与队列的括号匹配、后缀表达式求值等,还有树与二叉树的遍历、节点计数、度数计算及图的邻接矩阵、深度优先搜索和广度优先搜索。深入解析了排序算法如插入排序和希尔排序,以及数据结构和算法的关键知识点。
摘要由CSDN通过智能技术生成

线性表

1.统计单链表中结点的值小于给定值x的结点数

int Count(Linklist head)
{
    int c=0;
    Linklist p;
    p=head->next;
    while(p)
    {
        if(p->data<x)
            c++;
        p=p->next;
    }
    return c;
}

2.已知L1,L2分别为两循环单链表的头结点指针,m,n分别为L1,L2中数据结点个数,要求将两表合成一个带头结点的循环单链表

LinkList Union(LinkList L1,LinkList L2,int m,int n)
{
    if(m<0||n<0)
    {
        cout<<"error";
        exit(0);
    }
    if(m<n)
    {
        if(m==0)
            return L2;
        else {
            LinkList p=L1;
            while(p->next!=L1)//因为是循环单链表
                p=p->next;//找最后一个结点
            p->next=L2->next;
            L2->next=L1->next;
            free(L1);
        }
    }
    else {
        if(n==0)
            return L1;
        else {
            Linklist p=L2;
            while(p->next!=L2.first)//因为是循环单链表
                p=p->next;
            p->next=L1->next;
            L1->next=L2->next;
            free(L2);
    }
}

3.从有序表A中删除和有序表B中元素相同的结点

4.头插法与尾插法

LinkList::LinkList(int a[],int n)//头插法
{
    first=new Node;
    first->next=NULL;
    Node *s;
    for(int i=0;i<n;i++)
    {
        s=new Node;
        s->data=a[i];
        s->next=first->next;
        first->next=s;
    }
}
LinkList::LinkList(int a[],int n)//尾插法
{
    first=new Node;
    first->next=NULL;
    Node *s,*r=first;
    for(int i=0;i<n;i++)
    {
        s=new Node;
        s->data=a[i];
        r->next=s;
        r=s;
    }
    r->next=NULL;
}

5.基本操作
删除

LinkList::~LinkList()
{
    Node *p=first;
    while(first!=NULL)
    {
        first=first->next;
        delete p;
        p=first;
    }
}

求长度

LinkList::Length()
{
    int m=0;
    Node *p=first->next;
    while(p!=NULL)
    {
        c++;
        p=p->next;
    }
    return c;
}

获取第i个位置的数

int LinkList::Get(int i)
{
    Node *p=first->next;
    int c=1;
    while(p!=NULL&&c<i)
    {
        p=p->next;
        c++;
    }
    if(p==NULL)
        throw"查找位置错误";
    else return p->data;
}

获取数x的位置

int LinkList::Locate(int x)
{
    Node *p=first->next;
    int c=1;
    while(p!=NULL)
    {
        if(p->data==x)
            return c;
        p=p->next;
        c++;
    }
    return 0;//用于判断是否找到
}

插入

void LinkList::Insert(int i,int x)
{
    Node *p=first,*s=NULL;
    int c=0;
    while(p!=NULL&&c<i-1)
    {
        p=p->next;
        c++;
    }
    if(p==NULL)
        throw"插入位置错误";
    else{
        s=new Node;
        s->data=x;
        s->next=p->next;
        p->next=s;
    }
}

删除

int LinkList::Delete(int i)
{
    Node *p=first,*s=NULL;
    int x;
    while(p!=NULL&&c<i-1)
    {
        p=p->next;
        c++;
    }
    if(p==NULL||p->next==NULL)
        throw"删除位置错误";
    else{
        s=p->next;
        p->next=s->next;
        x=s->data;
        delete s;
        return x;
    }
}

6.构造有序双链表

void doublelink::Insert(int x)
{
    node *p=first->next,*s,*q=first;
    s=new node;
    s->data=x;
    s->next=NULL;
    while(p)
    {
        if(p->data>=x)
        {
            s->next=p;
            s->piror=q;
            q->next=s;
            p->piror=s;
            break;
        }
        q=p;
        p=p->next;
    }
    if(p==NULL)
    {
        s->piror=q;
        s->next=q->next;
        q->next=s;
    }
}

7.构造有序单链表

void LinkList::Insert(int x)
{
    node *p=first->next,*s,*r=first;
    s=new node;
    s->data=x;
    while(p&&x>p->data)
    {
        r=p;
        p=p->next;
    }
    s->next=p;
    r->next=s;
}

栈和队列

1.括号匹配
简单

#include<iostream>
using namespace std;

int main()
{
    string s;
    cin>>s;
    int t=0;
    for(int i=0; i<=s.length(); i++)
    {
        if(s[i]=='(')
            t++;
        else if(s[i]==')')
            t--;
        if(t<0)
            break;
    }
    if(t==0)
        cout<<"Yes"<<endl;
    else cout<<"No"<<endl;
    return 0;
}

复杂

void match(LinkStack &s,char ch[])
{
    char c;
    for(int i=0; ch[i]!=NULL; i++)
    {
        switch(ch[i])
        {
        case'(':
        case'[':
        case'{':
            s.Push(ch[i]);
            break;
        case')':
        case']':
        case'}':
            if(s.Empty())
            {
                cout<<"多右括号"<<endl;
                return ;
            }
            else
            {
                c=s.GetTop();
                if(ch[i]==')'&&c=='('||ch[i]==']'&&c=='['||ch[i]=='}'&&c=='{')
                {
                    s.Pop();
                    break;
                }
                else
                {
                    cout<<"匹配失败"<<endl;
                    return ;
                }
            }
        }
    }
    if(s.Empty())
        cout<<"匹配成功"<<endl;
    else cout<<"多左括号"<<endl;
}

后缀表达式求值

#include<iostream>
#include<stack>
using namespace std;
stack<int>s;

int main()
{
    string str;
    int x,y;
    while(cin>>str)
    {
        if(str=="+")
        {
            x=s.top();
            s.pop();
            y=s.top();
            s.pop();
            s.push(x+y);
        }
        else if(str=="-")
        {
            x=s.top();
            s.pop();
            y=s.top();
            s.pop();
            s.push(y-x);
        }
        else if(str=="*")
        {   x=s.top();
            s.pop();
            y=s.top();
            s.pop();
            s.push(x*y);
        }
        else if(str=="/")
        {   x=s.top();
            s.pop();
            y=s.top();
            s.pop();
            s.push(y/x);
        }
        else
        {
            int n=0;
            for(int i=0; i<str.length(); i++)
            {
                n=n*10+str[i]-'0';
            }
            s.push(n);
        }
    }
    cout<<s.top()<<endl;
    return 0;
}

十进制转化为二进制

#include<iostream>
#include<stack>
using namespace std;

int main()
{
    int n;
    cin>>n;
    stack<int>s;
    while(n!=0)
    {
        s.push(n&1);
        n>>=1;
    }
    while(!s.empty())
    {   cout<<s.top();
        s.pop();
    }
    return 0;
}

树和二叉树

1.前中后序遍历二叉树

void PreOrder(BiNode *root)
{
    if(root!=NULL)
    {
        cout<<root->data;
        PreOrder(root->lchild);
        PreOrder(root->rchild);
    }
}
void InOrder(BiNode *root)
{
    if(root!=NULL)
    {
        InOrder(root->lchild);
        cout<<root->data;
        InOrder(root->rchild);
    }
}
void PostOrder(BiNode *root)
{
    if(root!=NULL)
    {
        PostOrder(root->lchild);
        PostOrder(root->rchild);
        cout<<root->data;
    }
}
void PreOrder(int root,char data[])
{
    if(data[root]!='\0')
    {
        cout<<data[root];
        PreOrder(2*root,data);
        PreOrder(2*root+1,data);
    }
}
void InOrder(int root,char data[])
{
    if(data[root]!='\0')
    {
        InOrder(2*root,data);
        cout<<data[root];
        InOrder(2*root+1,data);
    }
}
void PostOrder(int root,char data[])
{
    if(data[root]!='\0')
    {
        PostOrder(2*root,data);
        PostOrder(2*root+1,data);
        cout<<data[root];
    }
}

层序遍历

void BiTree::LeverOrder( )
{
    BiNode *Q[100],*q=NULL;//顺序队列最多100个结点
    int front=-1,rear=-1; //队列初始化
    if(root==NULL)
        return;
    Q[++rear]=root;//根指针入队
    while(front!=rear)//当队列非空时
    {
        q=Q[++front];//出队
        cout<<q->data;
        if(q->lchild!=NULL)
            Q[++rear]=q->lchild;
        if(q->rchild!=NULL)
            Q[++rear]=q->rchild;
    }
}

void BiTree::LevelOrder(BiNode *root)
{
    queue<BiNode*>a;
    if(root)
        a.push(root);
    while(!a.empty())
    {
        root=a.front();
        a.pop();
        cout<<root->data;
        if(root->lchild)
            a.push(root->lchild);
        if(root->rchild)
            a.push(root->rchild);
        
    }
}

求二叉树的结点个数:

void Count(BiNode *root)
{
    if(root)
    {
        Count(root->lchild);
        number++;
        Count(root->rchild);
    }
}

求叶子结点个数:

int leaf=0;
void constleaf(BiNode *root)
{
    if(root)
    {
        if(root->lchild==NULL&&root->rchild==NULL)
            leaf++;
        else
        {
            constleaf(root->lchild);
            constleaf(root->rchild);
        }
    }
}
//或
int LeavesNumber(struct treeNode* root)
{
	if(root == NULL)
		return 0;
	else if((root->LChild == NULL) && (root->RChild == NULL))
		return 1;
	else
		return (LeavesNumber(root->LChild) + LeavesNumber(root->RChild));
}

求树的高度

int BiTree::cal_height(BiNode *root)
{
    int lheight=0,rheight=0;
    if(root==NULL)
        return 0;
    lheight=cal_height(root->lchild);
    rheight=cal_height(root->rchild);
    if(lheight>rheight)
        return lheight+1;
    else return rheight+1;
    
}

打印度为0,1,2的结点个数

void leaf(btree* T,int &count)//count 起计数作用 
{
	if(T == NULL) //跳出递归条件 
		return;
	if(T->lchild == NULL&&T->rchild == NULL)//关系运算优先级== 大于逻辑运算&& 
		count++;
	leaf(T->rchild,count);//可以与下式调换位置 
	leaf(T->lchild,count);
}

/*求二叉树中度为1结点个数*/

void degree1(btree* T,int &count)
{
	if(T == NULL)
		return;
	if((T->lchild == NULL &&T->rchild != NULL)||(T->rchild == NULL &&T->lchild != NULL))
		count++;
	degree1(T->lchild,count);
	degree1(T->rchild,count); 
}
/*求二叉树度为2的点*/ 
void degree2(btree *T,int &count)
{
	if(T == NULL)
		return;
	if(T->lchild != NULL&&T->rchild != NULL)
		count++;
	degree2(T->lchild,count);
	degree2(T->rchild,count);
}

//计算二叉树中度为1的结点总数
int leaf_1(BiTreeNode *T) {
	if (T==NULL) {
		return 0;
	}
	if ((T->leftchild == NULL && T->rightchild != NULL) || (T->leftchild != NULL && T->rightchild == NULL))
	{
		return 1 + leaf_1(T->leftchild) + leaf_1(T->rightchild);
	}
	return leaf_1(T->leftchild) + leaf_1(T->rightchild);
}

《数据结构习题——求二叉树的深度与宽度》

1.邻接矩阵

Mgraph::Mgraph(int a[],int n,int e)
{
    int i,j,k;
    vertexNum=n;
    edgeNum=e;
    for(i=0; i<vertexNum; i++)
        vertex[i]=a[i];//顶点数组赋值
    for(i=0; i<vertexNum; i++)
        for(j=0; j<vertexNum; j++)
            edge[i][j]=0;//边数组初始化
    for(k=0; k<edgeNum; k++) //给边赋值
    {
        cin>>i>>j;
        edge[i][j]=1;
        edge[j][i]=1;//无向图,若想变成有向图,只需要删除本句
    }
}

2.DFS

void Mgraph::DFSTraverse(int v)
{
    cout<<vertex[v];//访问顶点
    visited[v]=1;//置顶点被访问过
    for(int j=0; j<vertexNum; j++)
    {
        if(edge[v][j]==1&&visited[j]==0)
            DFSTraverse(j);
    }
}

3.BFS

void Mgraph::BFSTraverse(int v)
{
    int w,j,Q[MaxSize];
    int front=-1,rear=-1;
    cout<<vertex[v];//访问顶点
    visited[v]=1;//置顶点被访问过
    Q[++rear]=v;
    while(front!=rear)
    {
        w=Q[++front];//队头元素出队
        for(j=0; j<vertexNum; j++)
        {
            if(edge[w][j]==1&&visited[j]==0)
            {
                cout<<vertex[j];
                visited[j]=1;
                Q[++rear]=j;
            }
        }
    }
}

4.邻接表

ALGraph::ALGraph(int a[],int n,int e)
{
    int i,j,k;
    EdgeNode *s=NULL;
    vertexNum=n;
    edgeNum=e;
    for(i=0;i<vertexNum;i++)//初始化顶点表
    {
        adjlist[i].vertex=a[i];
        adjlist[i].firstEdge=NULL;
    }
    for(k=0;k<edgeNum;k++)
    {
        cin>>i>>j;
        s=new EdgeNode;
        s->adjvex=j;
        s->next=adjlist[i].firstEdge;
        adjlist[i].firstEdge=s;//头插法
    }
}

5.DFS

void ALGraph::DFSTraverse(int v)
{
    int j;
    EdgeNode *p=NULL;
    cout<<adjlist[v].vertex;
    visited[v]=1;
    p=adjlist[v].firstEdge; //工作指针p指向顶点v的边表
    while(p!=NULL)
    {
        j=p->adjvex;
        if(visited[j]==0)
            DFSTraverse(j);
        p=p->next;
    }
}

6.BFS

void ALGraph::BFSTraverse(int v)
{
    int w,j,Q[MaxSize];
    int front=-1,rear=-1;
    EdgeNode *p=NULL;
    cout<<adjlist[v].vertex;
    visited[v]=1;
    Q[++rear]=v;
    while(front!=rear)
    {
        w=Q[++front];
        p=adjlist[w].firstEdge;
        while(p!=NULL)
        {
            j=p->adjvex;
            if(visited[j]==0)
            {
                cout<<adjlist[j].vertex;
                visited[j]=1;
                Q[++rear]=j;
            }
            p=p->next;
        }
    }
}

排序

1.直接插入排序

void insertSort(int r[],int n)
{
    int j=0;
    for(int i=2;i<=n;i++)
    {
        r[0]=r[i];
        j=i-1;
        while(r[j]>r[0])
        {
            r[j+1]=r[j];
            j--;
        }
        r[j+1]=r[0];
    }
}

2.希尔排序

void ShellSort(int r[],int n)
{
    for(int d=n/2;d>=1;d=d/2)
    {
        for(int i=d+1;i<=n;i++)
        {
            r[0]=r[i];
            int j=i-d;
            while(j>0&&r[j]>r[0])
            {
                r[j+d]=r[j];
                j=j-d;
            }
            r[j+d]=r[0];
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值