王道1-2章重点算法题

12 篇文章 0 订阅
8 篇文章 0 订阅
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
#define MAXSIZE 20
//顺序表
typedef struct
{
 int data[MAXSIZE];
 int length;
}Sqlist;
//链表
typedef struct Lnode
{
 int data;
 struct Lnode* next;
}*LinkList, Lnode;
//初始化
void Init_Sqist(Sqlist& L)
{
 L.length = 0;
}
void Init_LinkList(LinkList head)
{
 head->next = NULL;
}
//题目:两个顺序表A[],B[](有序递增),合成一个顺序表到A[],且不设新的顺序表存储空间
bool merge(Sqlist &A,Sqlist B)
{
 if (A.length + B.length > MAXSIZE) return false;
 int i = A.length - 1;
 int j = B.length - 1;
 while (j >= 0 && i >= 0)
 {
  if (A.data[i] >= B.data[j])
  {
   A.data[i + j + 1] = A.data[i];
   i--;
  }
  else
  {
   A.data[i + j + 1] = B.data[j];
   j--;
  }
 }
 if (i == -1)
 {
  while (j >= 0)
  {
   A.data[j] = B.data[j];
   j--;
  }
 }
 A.length = A.length + B.length;
 return true;
}
//题目:设有一个表头结点指针为h的单链表,设计算法,通过一次遍历将链表中的所有结点链方向逆转
//单链表逆置
LinkList reverse_Link(LinkList &head)
{
 LinkList p;
 p = head->next;
 LinkList r = p;
 head->next = NULL;
 while (r)
 {
  p = p->next;
  r->next = head->next;
  head = r;
  r = p;
 }
}
//顺序表逆置
void reverse_Sqlist(Sqlist &L)
{
 int low=0;
 int high = L.length - 1;
 int temp;
 while (low++ < high—-)
 {
  temp = L.data[low];
  L.data[low] = L.data[high];
  L.data[high] = temp;
 }
}
//题目:对长度为n的顺序表L,编写一个时间复杂度为o(n)空间复杂度为o(1)的算法,该算法删除线性表中所有值为x的数据元素
void Delete_repeat(Sqlist &L,int x)
{
 int count = 0;
 int i;
 for (i=0;i<L.length;i++)
 {
  if (L.data[i] == x)
  {
   count++;
  }
  else
  {
   L.data[i - count] = L.data[i];
  }
 }
 L.length = L.length - count;
}
//题目:从有顺序表中删除值重复的元素,使表中所有元素的值均不同
void Del_Same(Sqlist&L)
{
 int i,j;
 for (i = 0,j=1; j < L.length; j++)
 {
  if (L.data[i] == L.data[j])
  {
   
   L.length--;
  }
  else
  {
   L.data[i + 1] = L.data[j];
   i++;
   
  }
 }
}
//链表
//题目:两个整数序列为A:a1,a2,a3,a4,...am和B=b1,b2,b3.....bn,已经存入两个单链表中,设计一个算法判断序列B是序列A的连续子序列
bool Is_Include(LinkList A,LinkList B)
{
 LinkList pa, pb, temp;
 pa = temp = A->next;
 pb = B->next;
 while (pb&&pa)
 {
   if (pb->data == pa->data)
   {
  pb = pb->next;
  pa = pa->next;
   }
   else
   {
  temp = temp->next;
  pa = temp;
  pb = B->next;
   }
 }
 if (pb == NULL)return true;
 else
 return false;
}
//题目:设有一个带头结点的循环单链表,其结点值均为正整数,设计一个算法,反复找出单链表中结点值最小的结点并输出,然后将该节点从中删除,直到单链表为空为止,再删除表头结点
void Del_Orderly(LinkList &head)
{
 LinkList p, pre, min, premin;
 while (head->next!=head)
 {
  min = p = head->next;
  pre = premin = head;
  while (p)
  {
   if (p->data < min->data)
   {
    min = p;
    premin = pre;
    pre = p;
    p = p->next;
   }
   else
   {
    pre = p;
    p = p->next;
   }
  }
  cout << min->data;
  premin->next = min->next;
  free(min);
 }
 free(head);
}
//题目:将一个带有头结点的但链表A分解为两个带头结点的单链表A,和B,使得表中含有原来序号为奇数的元素,而B表中含有原表中序号为偶数的元素,且保持相对顺序不变
void Divide_Odd(LinkList& A, LinkList& B)
{
 LinkList pa, pb,r;
 r = B;
 if (A->next && A->next->next)
 {
  pa = A->next;
  pb = A->next->next;
  while (pb&&pa)
  {
   pa->next = pb->next;
   pa = pb->next;
   r->next = pb;
   r = pb;
   pb = pa->next;
  }
  r->next = NULL;
 }
}
//题目:给定一个带表头结点的单链表,设head为头指针,试写出算法:按递增次序输出单链表中各个结点的数据元素,并释放结点所占的空间(不允许使用数组)
void Del_increase(LinkList &head)
{
 LinkList pre, p;
 while (head->next)
 {
  pre = head;
  p = head->next;
  while (p->next)
  {
   if (pre->next->data < p->next->data)
    pre = p;
   p = p->next;
  }
  p = pre->next;
  pre->next = p->next;
  free(p);
 }
 free(head);
}
//题目:假设有两个按元素值递增次序排列的线性表,均以单链表形式存储,请编写算法将这两个单链表归并为一个按元素值递减次序排列的单链表,并要求利用原来的两个单链表的结点存放归并后的单链表
void Merge_Desc(LinkList &A,LinkList&B)
{
 LinkList p = A->next;
 LinkList q = B->next;
 A->next = NULL;
 free(B);
 LinkList r;
 while (p && q)
 {
  if (p->data >= q->data)
  {
   r = q->next;
   p->next = A->next;
   A->next = p;
   p = r;
  }
  else
  {
   r = p->next;
   p->next = A->next;
   A->next = p;
   p = r;
  }
 }
 while (p)
 {
  r = p->next;
  p->next = A->next;
  A->next = p;
  p = r;
 }
 while (q)
 {
  r = q->next;
  q->next = A->next;
  A->next = q;
  q = r;
 }
}
//题目:设线性表,L(a1,a2,a3,...,an-2,an-1,an)采用带头结点的单链表保存,设计一个空间复杂度为o(1)且时间上尽可能高效的算法,重新排列高级的算法,重新排列L中的各个节点,得到线性表L(a1,an,a2,an-1,a3,an-2...)
void change_list(LinkList&head)
{
 //把后半段拆下来
 LinkList a, b;
 a = head;
 b = head;
 while (b->next)
 {
  a = a->next;
  b = b->next;
  if (b->next)
  {
   b = b->next;
  }
 }
 LinkList B = a->next;
 a->next = NULL;
 //转置B
 LinkList s = B->next;
 LinkList r = s;
 B->next = NULL;
 while (s)
 {
  r = s->next;
  s->next = B->next;
  b->next = s;
  s = r;
 }
 //二合一
 a = head->next;
 b = B->next;
 r = b;
 B->next = NULL;
 free(B);
 while (a&&b)
 {
  r = b->next;
  b->next = a->next;
  a->next = b;
  b = r;
  a = a->next->next;
 }
}
void PrintSqlist(Sqlist L)
{
 int i = 0;
 for (i; i < L.length; i++)
 {
  printf("%d\t", L.data[i]);
 }
 printf("\n");
}
int  main()
{
 Sqlist A;
 Sqlist B;
 merge(A,B);
 PrintSqlist(A);
 return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值