数据结构题

Posted by violetks on November 2, 2019

实验一:数制转换

实验名称:实现十进制整数 N 向其它进制数 d(二、八、十六)的转换。
【数据结构】

#define S_SIZE 100 //栈的空间大小

#define STACKINCREAMENT 10 //增加空间

struct SqStack{
  int *base; //栈底
  int *top; //栈顶
  int stacksize; //栈当前的存储空间
};

【算法思想】

void InitStack(SqStack &S); //初始化空栈
int StackEmpty(SqStack S); //判空
void GetTop(SqStack S, int &e);//获得栈顶元素
void push(SqStack &S, int e);//进栈
void pop(SqStack &S, int &e);//出栈
void convert(SqStack &S, int N, int n);//十进制转 N 进制

unsigned n, N;//要转换成的进制数和要转换的数
SqStack s;
InitStack(s);//初始化空栈
printf("输入要转换的十进制数和要转换为的进制数:\n");
scanf("%d,%d", &N, &n);
printf("%d 转换为%d 进制后为:\n", N, n);
convert(s, N, n);

【算法描述】

void InitStack(SqStack &S)
{
  S.base = (int *)malloc(S_SIZE*sizeof(int));
  S.stacksize = S_SIZE;
  S.top = S.base;//初始化空栈
}
int StackEmpty(SqStack S)
{
  if (S.base == S.top)
    return 1;
  else
    return 0;
}
void GetTop(SqStack S, int &e)
{//获得栈顶元素
  e = *(S.top - 1);
}
void push(SqStack &S, int e)
{//进栈
  if (S.top - S.base >= S.stacksize)
  {
    S.base=(int *)realloc(S.base,(S.stacksize+STACKINCREAMENT)*sizeof(int));
    S.top=S.base+S.stacksize;
    S.stacksize+=STACKINCREAMENT;
  }
  *(S.top)=e;
  S.top++;
}
void pop(SqStack &S,int &e)
{//出栈
  if(S.base !=S.top)
  {
    S.top--;
    e=*S.top;
  }
}
void convert(SqStack &S, int N,int n)
{
  InitStack(S);
  do{
    push(S,N%n);
    N /= n;
  }while(N!=0);
  int e;
  while(!StackEmpty(S))
  {
    pop(S,e);
    if(e>9)//十六进制时输出字母
    {
      e=e+55;
      printf("%c",e);
    }else
      printf("%d",e);
  }
  printf("\n");
}

a8DTTU.png

实验二:单链表的插入删除

#include<stdio.h>

#include<stdlib.h>

#include<malloc.h>

#define M 100

typedef int Etype; //定义单链表结点值的类型为整型

typedef struct Node
{
  Etype data;	        //单链表中的数据域
  struct Node *link;  //单链表的指针域
}Node;
typedef Node *List;	//定义单链表

List BuildList1();
List BuildList2();
void PrintList(List first);
void clear(List *first);

//头插法建立链表
List BuildList1()
{
  Node *L;
  Etype x,n;
  L = (Node *)malloc(sizeof(Node));	//申请头结点空间
  L->link = NULL;	//初始化一个空链表printf("请输入元素个数:\n");
  scanf("%d",&n);
  printf("请输入元素:\n");	//x 为链表数据域中的数据
  for(int i=0;i<n;i++)
  {
    scanf("%d",&x);
    Node *p;
    p = (Node *)malloc(sizeof(Node));		//申请新的结点
    p->data = x;	//结点数据域赋值
    p->link = L->link;	//将结点插入到表头 L-->|2|-->|1|-->NULL
    L->link = p;
  }
  return L;
}

//尾插法建立链表
List BuildList2()
{
  Node *L,*r;
  Etype n,x;
  L = (Node *)malloc(sizeof(Node));		//申请头结点空间
  L->link = NULL;	//初始化一个空链表
  printf("请输入元素个数:\n");
  scanf("%d",&n);
  r = L;	//r 始终指向终端结点,开始时指向头结点
  printf("请输入元素:\n");
  for(int i=0;i<n;i++)
  {
    scanf("%d",&x);
    Node *p;
    p = (Node *)malloc(sizeof(Node));	//申请新的结点
    p->data = x;	//结点数据域赋值
    r->link = p;	//将结点插入到表头 L-->|1|-->|2|-->NULL
    r = p;
  }
  r->link = NULL;

  return L;
}

//输出链表
void PrintList(List first)
{
  Node *Li;
  if(first==NULL)
  {
    printf("链表为空!\n");
    return;
  }
  Li=first->link;
  while(Li!=NULL)
  {
    printf("%d ",Li->data);
    Li=Li->link;
  }
  printf("\n");
}

//清空链表
void clear(List *first)
{
  Node *p=*first;
  while(*first)
  {
    p=(*first)->link;
    free(*first);
    *first=p;
  }
}
int main()
{
  Node *L;
  L=BuildList1(); //调用 BuiltdList1(前插法)建立单链表算法
  PrintList(L); //打印单链表
  clear(&L);//清空单链表
  L=BuildList2(); //调用 BuiltdList2(后插法)建立单链表算法
  PrintList(L); //打印单链表
  clear(&L);//清空单链表
}

实验三:二叉树的遍历

#include<iostream.h>

struct BiNode
{
  char data;
  BiNode *lchild,*rchild;
};

class BiTree
{
  public:
  BiTree(){root=Creat(root);}
  ~BiTree(){Release(root);}
  void PreOrder(){PreOrder(root);}
  void InOrder(){InOrder(root);}
  void PostOrder(){PostOrder(root);}

  private:
  BiNode *root;
  BiNode *Creat(BiNode *bt);
  void Release(BiNode *bt);
  void PreOrder(BiNode *bt);
  void InOrder(BiNode *bt);
  void PostOrder(BiNode *bt);
};

BiNode *BiTree::Creat(BiNode *bt)
{
  char ch;
  cin>>ch;
  if(ch=='#')
    return NULL;
  else
  {
    bt=new BiNode;
    bt->data=ch;
    bt->lchild=Creat(bt->lchild);
    bt->rchild=Creat(bt->rchild);
  }
  return bt;
}

void BiTree::Release(BiNode *bt)
{
  if(bt!=NULL)
  {
    Release(bt->lchild);
    Release(bt->rchild);
    delete bt;
  }
}

void BiTree::PreOrder(BiNode *bt)
{
  if(bt==NULL)
    return;
  else
  {
    cout<<bt->data<<" ";
    PreOrder(bt->lchild);
    PreOrder(bt->rchild);
  }
}

void BiTree::InOrder(BiNode *bt)
{
  if(bt==NULL) return;
  else
  {
    InOrder(bt->lchild);
    cout<<bt->data<<" ";
    InOrder(bt->rchild);
  }
}

void BiTree::PostOrder(BiNode *bt)
{
  if(bt==NULL) return;
  else
  {
    PostOrder(bt->lchild);
    PostOrder(bt->rchild);
    cout<<bt->data<<" ";
  }
}

int main()
{
  cout<<"请输入创建一棵二叉树的结点数据"<<endl;
  BiTree T;
  cout<<"-----前序遍历	"<<endl;
  T.PreOrder();
  cout<<endl;
  cout<<"-----中序遍历	"<<endl;
  T.InOrder();
  cout<<endl;
  cout<<"-----后序遍历	"<<endl;
  T.PostOrder();
  cout<<endl;
  return 0;
}

a8DbY4.png

实验四:赫夫曼树

void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n) {
  // 算法 6.12
  // w 存放 n 个字符的权值(均>0),构造哈夫曼树 HT,
  // 并求出 n 个字符的哈夫曼编码 HC
  int i, j, m, s1, s2, start;
  char *cd;
  unsigned int c, f;

  if (n<=1) return;
  m = 2 * n - 1;
  HT = (HuffmanTree)malloc((m+1) * sizeof(HTNode)); // 0 号单元未用
  for (i=1; i<=n; i++) { //初始化
    HT[i].weight=w[i-1];
    HT[i].parent=0;
    HT[i].lchild=0;
    HT[i].rchild=0;
  }
  for (i=n+1; i<=m; i++) { //初始化
    HT[i].weight=0;
    HT[i].parent=0;
    HT[i].lchild=0;
    HT[i].rchild=0;
  }
  printf("\n 哈夫曼树的构造过程如下所示:\n");
  printf("HT 初态:\n 结点 weight parent lchild rchild");
  for (i=1; i<=m; i++)
    printf("\n%4d%8d%8d%8d%8d",i,HT[i].weight, HT[i].parent,HT[i].lchild, HT[i].rchild);
    printf(" 按任意键,继续 ...");
    getch();
  for (i=n+1; i<=m; i++) { // 建哈夫曼树
    // 在 HT[1..i-1]中选择 parent 为 0 且 weight 最小的两个结点,
    // 其序号分别为 s1 和 s2。
    Select(HT, i-1, s1, s2);
    HT[s1].parent = i; HT[s2].parent = i;
    HT[i].lchild = s1; HT[i].rchild = s2;
    HT[i].weight = HT[s1].weight + HT[s2].weight;
    printf("\nselect: s1=%d s2=%d\n", s1, s2);
    printf(" 结点 weight parent lchild rchild");
    for (j=1; j<=i; j++)
      printf("\n%4d%8d%8d%8d%8d",j,HT[j].weight, HT[j].parent,HT[j].lchild, HT[j].rchild);
      printf(" 按任意键,继续 ...");
      getch();
  }

  //--- 从叶子到根逆向求每个字符的哈夫曼编码 ---
  cd = (char *)malloc(n*sizeof(char)); // 分配求编码的工作空间
  cd[n-1] = '\0'; // 编码结束符。
  for (i=1; i<=n; ++i) { // 逐个字符求哈夫曼编码
    start = n-1; // 编码结束符位置
    for (c=i, f=HT[i].parent; f!=0; c=f, f=HT[f].parent)
      // 从叶子到根逆向求编码
      if (HT[f].lchild==c)
        cd[--start] = '0';
      else
        cd[--start] = '1';
    HC[i] = (char *)malloc((n-start)*sizeof(char)); // 为第 i 个字符编码分配空间
    strcpy(HC[i], &cd[start]); // 从 cd 复制编码(串)到 HC
  }
  free(cd); // 释放工作空间
} // HuffmanCoding

a8DHkF.png