#数据结构#复习--编程

第二章

顺序表的操作

#define MAXSIZE 100//存储空间初始分配量
typedef struct{
    ElemType *elem;
    int length;
    int listsize;
}SqList;

void InitList_Sq(SqList &L)//初始化
{
    L.elem = new ElemType[MaxSIZE];
    if(!L.elem)
        return;
    L.length = 0;
}

int LocateElem(SqList L,ElemType e)//查找
{
    for(int i = 0; i < L.length; i++)
    {
        if(L.elem[i] == e)
            return i + 1;
    }
    return 0;
        
}

void ListInsert(SqList &L, int i, ElemType e)//插入e
{
    if((i < 1) || (i > L.length + 1) || (L.length == MAXSIZE))
        return;//i值不合法,当前存储空间已满
    for(int j = L.length - 1; j >= i -1; j--)
    {
        L.elem[j + 1] = L.elem[j];
    }
    L.elem[i - 1] = e;
    ++L.length;
}

void ListDelete(SqList &L, int i)//删除
{
    for(int j = i; j <= L.length - 1; j++)
    {
        L.elem[j - 1] = L.elem[j];
    }
    --L.length;
}

void GetElem(SqList L, int i, ElemType &e)//取第i个元素的值
{
    if((i < 1) || (i > L.length))
        return;
    e = L.elem[i - 1];
}

单链表的操作

#define MAXSIZE 100//存储空间初始分配量
typedef struct LNode{
    ElemType data;
    struct LNode *next;
}LNode, *LinkList;

void InitList(LinkList &L)//初始化
{
    L = new LNode;
    L -> next = NULL;
}

void GetElem(LinkList L, int i, ElemType &e)//取第i个元素的值
{
    LinkList *p;
    p = L -> next;//p = (*l).next;
    j = 1;
    while(p && j < i)
    {
        p = p -> next;
        ++j;
    }
    if(!p || j > i)
        return ERROR;
    e = p -> data;
}

LNode *LocateElem(LinkList L,ElemType e)//查找
{
    p = L -> next;
    while(p && p -> data != e)
    {
        p = p -> next;
    }
    return p;

}

void ListInsert(LinkList &L, int i, ElemType e)//插入e
{
    p = L;
    j = 0;
    while(p && (j < i -1))
    {
        p = p -> next;
        ++j;
    }
    if(!p || j > i - 1)
        return ERROR;
    s = new LNode;
    s -> data = e;
    s -> next = p -> next;
    p -> next = s;
}

void ListDelete(LinkList &L, int i)//删除
{
    p = L;
    j = 0;
    while((p -> next) && (j < i - 1))
    {
        p = p -> next;
        ++j;
    }
    if(!(p -> next) || (j > i - 1))
        return ERROR;
    q = p -> next;
    p -> next = q -> next;
    delete q;
}

void CreatList_H(LinkList &L, int n)
{
    L = new LNode;
    L -> next = NULL;
    for(i = 0; i < n; ++i)
    {
        p = new LNode;
        cin>>p -> data;
        p -> next = L -> next;
        L -> next = p;
    }
}

void CreatList_R(LinkList &L, int n)
{
    L = new LNode;
    L -> next = NULL;
    r = L;
    for(i = 0; i < n; ++i)
    {
        p = new LNode;
        cin>>p -> data;
        p -> next = NULL;
        r -> next = p;
        r = p;
    }
}
int main()
{
	LinkList *h;
	ElemType e,ch;
	InitList(h);
	int i=1; 
	while((ch=getchar())!='\n')
	{
		ListInsert(h,i,ch);
		i++;
	}
	DispList(h);
	scanf("\n%d",&i);	
   	if(ListDelete(h,i,e))
	   printf("delete %dth: %c\n",i,e);
	else
	   printf("delete failed!\n");
	DispList(h);
	DestroyList(h);
	return 0;
}

线性表合并

void MergeList_Sq(SqList LA, SqList LB, SqList &LC)
{
    LC.length = LA.length + LB.length;
    LC.elem = new ElemType[LC.length];
    pc = LC.elem;
    pa = LA.elem;
    pb = LB.elem;
    pa_last = LA.elme + LA.length - 1;
    pb_last = LB.elem + LB.length - 1;
    while(pa <= pa_last && pb <= pb_last)
    {
        if(*pa <= pb)
            *pc++ = *pa++;
        else
            *pc++ = *pb++; 
    }
    while(pa <= pa_last)
        *pc++ = *pa++;
    while(pb <= pb_last)
        *pc++ = *pb++;
}

顺序表合并

#include<bits/stdc++.h>
using namespace std;

typedef int  ElemType;
typedef struct LNode
{
    ElemType data;
    struct LNode *next;
} LNode,*LinkList;

void Create(LinkList &L)
{
    LNode *p = L;
    int n;
    while((p->next) != NULL)
    {
        p = p->next;
    }
    cin>>n;
    while(n != -1)
    {
        LNode *tmp = (LNode*)malloc(sizeof(LNode));
        tmp -> data = n;
        p -> next = tmp;
        tmp -> next = NULL;
        cin>>n;
        p = p -> next;
    }
}
void Combine(LinkList &s1,LinkList &s2,LinkList &s3)
{
    LNode *l1, *l2, *l3;
    l1 = s1 -> next;
    l2 = s2 -> next;
    l3 = s3;
    while(l1 && l2)
    {
        if(l1 -> data <= l2 -> data)
        {
            l3 -> next = l1;
            l1 = l1 -> next;
        }
        else
        {
            l3 -> next = l2;
            l2 = l2 -> next;
        }
        l3 = l3 -> next;
    }
    l3 -> next = l1 ? l1 : l2;
    s1 -> next = NULL;
    s2 -> next = NULL;
}
void Print(LinkList &L)
{
    LNode *p = L -> next;
    if(p == NULL)
        cout<<"NULL";
    while(p != NULL)
    {
        if(p -> next != NULL)
            cout<<p -> data<<" ";
        else
            cout<<p -> data;
        p = p->next;
    }
}
int main()
{
    LinkList S1, S2, S3;
    S1 = (LinkList)malloc(sizeof(LNode));
    S1 -> next = NULL;
    S2 =(LinkList)malloc(sizeof(LNode));
    S2 -> next = NULL;
    S3 = (LinkList)malloc(sizeof(LNode));
    S3 -> next = NULL;
    Create(S1);
    Create(S2);
    Combine(S1, S2, S3);
    Print(S3);
    return 0;
}

两个有序链表序列的交集

#include<bits/stdc++.h>
using namespace std;

typedef int  ElemType;
typedef struct LNode
{
    ElemType data;
    struct LNode *next;
} LNode,*LinkList;

void Create(LinkList &L)
{
    LNode *p = L;
    int n;
    while((p->next) != NULL)
    {
        p = p->next;
    }
    cin>>n;
    while(n != -1)
    {
        LNode *tmp = (LNode*)malloc(sizeof(LNode));
        tmp -> data = n;
        p -> next = tmp;
        tmp -> next = NULL;
        cin>>n;
        p = p -> next;
    }
}
void Union(LinkList s1,LinkList s2,LinkList &s3)
{
    LNode *l1, *l2, *tmp, *cur = s3;
    l1 = s1 -> next;
    l2 = s2 -> next;
    while(l1&&l2)
    {
        if(l1 -> data < l2 -> data)
        {
            l1 = l1 -> next;
        }
        else if(l1 -> data > l2 -> data)
        {
            l2 = l2 -> next;
        }
        else
        {
            tmp = (LNode*)malloc(sizeof(LNode));
            tmp -> data = l1 -> data;
            tmp -> next = NULL;
            cur -> next = tmp;
            cur = tmp;
            l1 = l1 -> next;
            l2 = l2 -> next;
        }
    }
}
void Print(LinkList &L)
{
    LNode *p = L -> next;
    if(p == NULL)
        cout<<"NULL";
    while(p != NULL)
    {
        if(p -> next != NULL)
            cout<<p -> data<<" ";
        else
            cout<<p -> data;
        p = p->next;
    }
}
int main()
{
    LinkList S1, S2, S3;
    S1 = (LinkList)malloc(sizeof(LNode));
    S1 -> next = NULL;
    S2 =(LinkList)malloc(sizeof(LNode));
    S2 -> next = NULL;
    S3 = (LinkList)malloc(sizeof(LNode));
    S3 -> next = NULL;
    Create(S1);
    Create(S2);
    Union(S1, S2, S3);
    Print(S3);
    return 0;
}

(4)递增排列两个集合A和B 的差集

  • (即仅由在A中出现而不在B中出现的元素所构成的集合),并以同样的形式存储,同时返回该集合的元素个数。
  • [题目分析]
    求两个集合A和B的差集是指在A中删除A和B中共有的元素,即删除链表中的相应结点,所以要保存待删除结点的前驱,使用指针pre指向前驱结点。pa和pb分别是链表La和Lb的工作指针,初始化为相应链表的第一个结点,从第一个结点开始进行比较,当两个链表La和Lb均为到达表尾结点时,如果La表中的元素小于Lb表中的元素,pre置为La表的工作指针pa删除Lb表中的元素;如果其中一个表中的元素较小时,删除此表中较小的元素,此表的工作指针后移。当链表La和Lb有一个为空时,依次删除另一个非空表中的所有元素。
void Difference(LinkList& La, LinkList& Lb,int *n)
{//差集的结果存储于单链表La中,*n是结果集合中元素个数,调用时为0
      pa=La->next; pb=Lb->next;//pa和pb分别是链表La和Lb的工作指针,初始化为相应链表的第一个结点
      pre=La;//pre为La中pa所指结点的前驱结点的指针
      while(pa&&pb)
      {
          if(pa->data<q->data)
          {
              pre=pa;
              pa=pa->next;
              *n++;
          }//A链表中当前结点指针后移
          else if(pa->data>q->data)
              q=q->next;//B链表中当前结点指针后移
          else
          {
              pre->next=pa->next;//处理A,B中元素值相同的结点,应删除
              u=pa;
              pa=pa->next; 
              delete u;//删除结点
          }
      }
}

将两个递增的有序链表合并为一个递增的有序链表

  • 要求结果链表仍使用原来两个链表的存储空间, 不另外占用其它的存储空间。表中不允许有重复的数据

  • 分析
    合并后的新表使用头指针Lc指向,pa和pb分别是链表La和Lb的工作指针,初始化为相应链表的第一个结点,从第一个结点开始进行比较,当两个链表La和Lb均为到达表尾结点时,依次摘取其中较小者重新链接在Lc表的最后。如果两个表中的元素相等,只摘取La表中的元素,删除Lb表中的元素,这样确保合并后表中无重复的元素。当一个表到达表尾结点,为空时,将非空表的剩余元素直接链接在Lc表的最后。


void MergeList(LinkList &La,LinkList &Lb,LinkList &Lc)
{//合并链表La和Lb,合并后的新表使用头指针Lc指向
  pa=La->next;  pb=Lb->next;    
   //pa和pb分别是链表La和Lb的工作指针,初始化为相应链表的第一个结点
   Lc=pc=La;  //用La的头结点作为Lc的头结点
   while(pa && pb)
{if(pa->data<pb->data){pc->next=pa;pc=pa;pa=pa->next;}
     //取较小者La中的元素,将pa链接在pc的后面,pa指针后移
     else if(pa->data>pb->data) {pc->next=pb; pc=pb; pb=pb->next;}
      //取较小者Lb中的元素,将pb链接在pc的后面,pb指针后移
     else //相等时取La中的元素,删除Lb中的元素
{pc->next=pa;pc=pa;pa=pa->next;
      q=pb->next;delete pb ;pb =q;
}
     }
 pc->next=pa?pa:pb;    //插入剩余段
     delete Lb;            //释放Lb的头结点
}  

通过一趟遍历在单链表中确定值最大的结点

  • [题目分析]
    假定第一个结点中数据具有最大值,依次与下一个元素比较,若其小于下一个元素,则设其下一个元素为最大值,反复进行比较,直到遍历完该链表。
ElemType Max (LinkList L ){
	if(L->next==NULL) return NULL;
	pmax=L->next; //假定第一个结点中数据具有最大值
	p=L->next->next;
	while(p != NULL ){//如果下一个结点存在
		if(p->data > pmax->data) pmax=p;//如果p的值大于pmax的值,则重新赋值
		p=p->next;//遍历链表
	}
	return pmax->data;

通过遍历一趟,将链表中所有结点的链接方向逆转,仍利用原表的存储空间。

  • [题目分析]
    从首元结点开始,逐个地把链表L的当前结点p插入新的链表头部。
void  inverse(LinkList &L) 
{// 逆置带头结点的单链表 L
    p=L->next;  L->next=NULL;
    while ( p) {
        q=p->next;    // q指向*p的后继
        p->next=L->next;
        L->next=p;       // *p插入在头结点之后
        p = q;
    }
}

第三章

双栈结构

  • 将编号为0和1的两个栈存放于一个数组空间V[m]中,栈底分别处于数组的两端。当第0号栈的栈顶指针top[0]等于-1时该栈为空,当第1号栈的栈顶指针top[1]等于m时该栈为空。两个栈均从两端向中间增长。试编写双栈初始化,判断栈空、栈满、进栈和出栈等算法的函数。双栈数据结构的定义如下:
    Typedef struct
    {int top[2],bot[2]; //栈顶和栈底指针
    SElemType *V; //栈数组
    int m; //栈最大可容纳元素个数
    }DblStack

  • [题目分析]
    两栈共享向量空间,将两栈栈底设在向量两端,初始时,左栈顶指针为-1,右栈顶为m。两栈顶指针相邻时为栈满。两栈顶相向、迎面增长,栈顶指针指向栈顶元素。

  • 算法讨论]
    请注意算法中两栈入栈和退栈时的栈顶指针的计算。左栈是通常意义下的栈,而右栈入栈操作时,其栈顶指针左移(减1),退栈时,栈顶指针右移(加1)。

int Init()//初始化
{
    S.top[0]=-1;
    S.top[1]=m;
    return 1; //初始化成功
}

int push(stk S,int i,int x) //入栈操作,i为栈号,i=0表示左栈,i=1为右栈,x是入栈元素。入栈成功返回1,失败返回0
{
    if(i<0||i>1)
    {
        cout<<“栈号输入不对”<<endl;
        exit(0);
    }
    if(S.top[1]-S.top[0]==1)
    {
        cout<<“栈已满”<<endl;
        return(0);
    }
    switch(i)
    {
    case 0:
        S.V[++S.top[0]]=x;
        return(1);
        break;
    case 1:
        S.V[--S.top[1]]=x;
        return(1);
    }
}//push

ElemType pop(stk S,int i)//退栈。i代表栈号,i=0时为左栈,i=1时为右栈。退栈成功时返回退栈元素
{
    if(i<0 || i>1)
    {
        cout<<“栈号输入错误”<<endl;
        exit(0);
    }
    switch(i)
    {
    case 0:
        if(S.top[0]==-1)
        {
            cout<<"栈空"<<endl;
            return -1;
        }
        else return(S.V[S.top[0]--]);
    case 1:
        if(S.top[1]==m)
        {
            cout<<“栈空”<<endl;
            return(-1);
        }
        else
            return(S.V[S.top[1]++]);
    }
}

int Empty()
{
    return (S.top[0]==-1 && S.top[1]==m);
}

回文

  • 回文是指正读反读均相同的字符序列,如“abba”和“abdba”均是回文,但“good”不是回文。试写一个算法判定给定的字符向量是否为回文。(提示:将一半字符入栈)
  • [题目分析]
    将字符串前一半入栈,然后,栈中元素和字符串后一半进行比较。即将第一个出栈元素和后一半串中第一个字符比较,若相等,则再出栈一个元素与后一个字符比较,……,直至栈空,结论为字符序列是回文。在出栈元素与串中字符比较不等时,结论字符序列不是回文。
#define StackSize 100 //假定预分配的栈空间最多为100个元素
typedef char DataType;//假定栈元素的数据类型为字符
typedef struct
{
    DataType data[StackSize];
    int top;
} SeqStack;
int IsHuiwen( char *t)
{
    //判断t字符向量是否为回文,若是,返回1,否则返回0
    SeqStack s;
    int i, len;
    char temp;
    InitStack( &s);
    len=strlen(t); //求向量长度
    for ( i=0; i<len/2; i++)//将一半字符入栈
        Push( &s, t[i]);
    while( !EmptyStack( &s))
    {
        // 每弹出一个字符与相应字符比较
        temp=Pop (&s);
        if( temp!=S[i])  return 0 ;// 不等则返回0
        else i++;
    }
    return 1 ; // 比较完毕均相等则返回 1
}

第五章

二叉树四种遍历

//二叉树四种遍历
void InorderTraversal( BinTree BT )
{
    if(BT)
    {
        InorderTraversal(BT -> Left);
        printf(" %c", BT -> Data);
        InorderTraversal(BT -> Right);
    }
}
void PreorderTraversal( BinTree BT )
{
    if(BT)
    {
        printf(" %c", BT -> Data);
        PreorderTraversal(BT -> Left);
        PreorderTraversal(BT -> Right);
    }
}
void PostorderTraversal( BinTree BT )
{
    if(BT)
    {
        PostorderTraversal(BT -> Left);
        PostorderTraversal(BT -> Right);
        printf(" %c", BT -> Data);
    }

}
void LevelorderTraversal( BinTree BT )
{
    BinTree p;
    BinTree q[100];
    int flag = 0, i = 0;
    if(BT)
    {
        q[i++] = BT;
        while(flag != i)
        {
            p = q[flag++];
            printf(" %c", p -> Data);
            if(p -> Left != NULL)
            {
                q[i++] = p -> Left;
            }
            if(p -> Right != NULL)
            {
                q[i++] = p -> Right;
            }
        }

    }
}

先序遍历的顺序建立二叉链表

void CreatBiTree(BiTree &T)
{
    cin>>ch;
    if(ch == '#')
        T = NULL;//递归结束,建空树
    else
    {
        T = new BiTNode;
        T -> data = ch;
        CreatBiTree(T -> lchild);
        CreatBiTree(T -> rchild);
    }
}

计算二叉树深度

int Depth(BiTree T)
{
    if(T = NULL)
        return 0;
    else
    {
        m = Depth(T -> lchild);
        n = Depth(T -> rchild);
        if(m > n)
            return m + 1;
        else
            return n + 1;
    }
}

二叉树最大的宽度

  • 二叉树的最大宽度是指二叉树所有层中结点个数的最大值
  • [题目分析] 求最大宽度可采用层次遍历的方法,记下各层结点数,每层遍历完毕,若结点数大于原先最大宽度,则修改最大宽度。
int Width(BiTree bt)//求二叉树bt的最大宽度
{
    if (bt==null) return (0);  //空二叉树宽度为0
    else
    {
        BiTree Q[]; //Q是队列,元素为二叉树结点指针,容量足够大
        front=1;
        rear=1;
        last=1;
        //front队头指针,rear队尾指针,last同层最右结点在队列中的位置
        temp=0;
        maxw=0;       //temp记局部宽度, maxw记最大宽度
        Q[rear]=bt;           //根结点入队列
        while(front<=last)
        {
            p=Q[front++];
            temp++; //同层元素数加1
            if (p->lchild!=null)  Q[++rear]=p->lchild;   //左子女入队
            if (p->rchild!=null)  Q[++rear]=p->rchild;   //右子女入队
            if (front>last)      //一层结束,
            {
                last=rear;
                if(temp>maxw) 
                maxw=temp;//last指向下层最右元素, 更新当前最大宽度
                temp=0;
            }
        }
        return (maxw);
    }

根据后序和中序遍历输出先序遍历

#include<bits/stdc++.h>

using namespace std;

int in[101],post[101];

typedef struct BiTNode{
	int data;
	struct BiTNode *lchild;
	struct BiTNode *rchild;
}BiTNode,*BiTree;

BiTree Build(int *in,int *post,int n)
{
	if(n <= 0)
		return NULL;
	int *p = in;
	while(p){
		if(*p == *(post + n - 1))
			break;
		p++;
	}
	BiTree T = new BiTNode;
	T -> data = *p;
	int len = p - in;
	T -> lchild = Build(in, post, len);
	T -> rchild = Build(p + 1, post + len, n - len - 1);
	return T;
}

void  PreorderPrintLeaves(BiTree T)
{
	if(T){
		printf(" %d",T -> data);
        PreorderPrintLeaves(T->lchild);
        PreorderPrintLeaves(T->rchild);
	}
	return;
}
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
	int n, i;
	BiTree T;
	cin>>n;
	for(i = 0;i < n;i++)
		scanf("%d",&post[i]);
	for(i = 0;i < n;i++)
		scanf("%d",&in[i]);
	T = Build(in,post,n);
	printf("Preorder:");
	 PreorderPrintLeaves(T);
	return 0;
}

家谱处理

#include <bits/stdc++.h>

using namespace std;

int main()
{
    vector<string> name(101);     
    map<string, string> father; 
    int n, m;
    scanf("%d %d", &n, &m);
    getchar();
    while(n--)
    {
        string str;
        getline(cin, str);
        int cnt = count(str.begin(), str.end(), ' ');
        if(cnt == 0)
        {
            father[str] = "root";
            name[0] = str;
        }
        else
        {
            str = str.substr(cnt);
            father[str] = name[cnt / 2 - 1];
            name[cnt / 2] = str;
        }
    }
    while(m--)
    {
        string a, b, c, d;
        cin >> a >> b >> b >> c >> b >> d;
        switch(c[0])
        {
            case 'p':
                swap(a, d);
            case 'c':
                if(father[a] == d)
                    printf("True\n");
                else
                    printf("False\n");
                break;
            case 's':
                if(father[a] == father[d])
                    printf("True\n");
                else
                    printf("False\n");
                break;
            case 'a':
                swap(a, d);
            case 'd':
                while(father[a] != d && father[a] != "root") 
                    a = father[a];
                if(father[a] == "root")
                    printf("False\n");
                else
                    printf("True\n");
        }
    }
    return 0;
}

修理牧场

#include <bits/stdc++.h>

using namespace std;

int main()
{
    priority_queue<int,vector<int>,greater<int> >l;
    int n, data, i;
    cin>>n;
    for(i = 0; i < n; i++)
    {
        cin>>data;
        l.push(data);
    }
    int sum = 0;
    while(l.size() != 1)
    {
        int x = l.top();
        l.pop();
        int y = l.top();
        l.pop();
        sum += x + y;
        l.push(x + y);
    }
    printf("%d\n", sum);
    return 0;
}

第八章

希尔排序

void   ShellSort(SqList &L,int dlta[ ]int t){
        //按增量序列dlta[0…t-1]对顺序表L作Shell排序
   for(k=0;k<t;++k)
     ShellInsert(L,dlta[k]);
   //增量为dlta[k]的一趟插入排序
}  // ShellSort

void   ShellInsert(SqList &L,int dk) 
{
      for(i=dk+1;i<=L.length; ++ i)
         if(r[i].key < r[i-dk].key) 
         {         
            r[0]=r[i]for(j=i-dk; j>0 &&(r[0].key<r[j].key); j=j-dk)
	 r[j+dk]=r[j];
        r[j+dk]=r[0]}
}

冒泡排序

void main() 			 
{	int a[11];		/*a[0]不用,之用a[1]~a[10]*/
	int i,j,t;
	printf("\nInput 10 numbers: \n");
	for(i=1;i<=10;i++)	scanf("%d",&a[i]);	printf("\n");
	for(j=1;j<=9;j++)
	    for(i=1;i<=10-j;i++)
	      if(a[i]>a[i+1])	{t=a[i];a[i]=a[i+1];a[i+1]=t;}//交换
	for(i=1;i<=10;i++)	printf("%d ",a[i]);   
}

选择排序

void SelectSort(SqList &K)
 { 
    for (i=1; i<L.length; ++i)
    { //在L.r[i..L.length] 中选择key最小的记录
        k=i;     
        for( j=i+1;j<=L.length ; j++)
            if ( L.r[j].key <L.r[k].key) k=j; 
        if(k!=i)L.r[i]←→L.r[k];            
    }  
}

快速排序

func Quick2Sort(values []int) {
    if len(values) <= 1 {
        return
    }
    mid, i := values[0], 1
    head, tail := 0, len(values)-1
    for head < tail {
        fmt.Println(values)
        if values[i] > mid {
            values[i], values[tail] = values[tail], values[i]
            tail--
        } else {
            values[i], values[head] = values[head], values[i]
            head++
            i++
        }
    }
    values[head] = mid
    Quick2Sort(values[:head])
    Quick2Sort(values[head+1:])
}
发布了145 篇原创文章 · 获赞 8 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43476037/article/details/103150933
今日推荐