| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3112 人关注过本帖, 2 人收藏
标题:用有序表表示集合并实现集合的并、交、差三种操作
只看楼主 加入收藏
qzt040613
Rank: 3Rank: 3
等 级:新手上路
威 望:6
帖 子:63
专家分:0
注 册:2006-3-15
收藏(2)
 问题点数:0 回复次数:2 
用有序表表示集合并实现集合的并、交、差三种操作

// 结构定义
  typedef struct LNode { // 结点结构
   ElemType data;
   struct LNode *next;
  } *SLink;
 
  讨论利用有序表表示集合并实现集合的并、交、差三种操作。

  以链式存储结构表示有序表,首先定义一个有序链表类型。
 

  typedef struct {     // 链表结构
   SLink head,       // 指向有序链表中的头结点
      tail,       // 指向有序链表中最后一个结点
      curPtr;      // 指向操作的当前结点,称为"当前指针"
   int length,       // 指示有序链表的长度
     curPos;       // 指示当前指针所指结点的位序
  } OrderedLinkList;

其中部分操作的伪码算法如下:

  bool MakeNode( SLink &p, ElemType e )
 {
  // 生成一个数据元素和 e 相同的新结点 *p,并返回TRUE,
  // 若存储分配失败,则返回 FALSE。
  p = new LNode;
  if (!p) return FALSE;
  p->data = e; p->next = NULL;
  return TRUE;
 }

  bool InitList( OrderedLinkList &L )
 {
  // 构造一个空的有序链表 L,若存储分配失败,
  // L.head = NULL 并返回 FALSE,否则返回 TRUE。
  if ( MakeNode( L.head, 0 ) )
  { L.tail = L.curPtr = L.head;
    L.length= L.curPos = 0;
    return TRUE; }
  else
  { L.head = NULL;
    return FALSE; }
 } // InitList

  bool GetPos (OrderedLinkList L, int pos )
 {
  // 若1≤pos≤LengthList(L),则移动当前指针指向第pos个结点,
  // 且返回函数值为TRUE,否则不移动当前指针且返回函数值为FALSE。
  if ( pos < 1 || pos > L.len )
   return FALSE;
  if ( L.curPos > pos )
  { L.curPtr = L.head -> next; L.curPos = 1; }
  while ( L.curPos < pos )
  { L.curPtr = L.curPtr -> next; ++L.curPos; }
  return TRUE;
 }

bool LocateElem ( OrderedLinkList L, ElemType e,
           int ( *compare )( ElemType, ElemType ) )
 {
 // 若有序链表L中存在和e相同的数据元素,则当前指针指向第1个
 // 和e相同的结点,并返回 TRUE,
 // 否则当前指针指向第一个大于e 的元素的前驱,并返回FALSE。
  L.current = L.head; L.curPos = 0;
  while ( L.current -> next &&
          compare( e,L.current -> next -> data )> 0 )
  {
   L.current = L.current -> next;  // 指针后移,继续查询
   L.curPos ++;
  }
  if ( L.current -> next &&
          compare( e,L.current -> next -> data ) == 0 )
  {                  // 查到和 e 相同元素,当前指针后移
   L.current = L.current -> next; L.curPos ++;
   return TRUE;
  }
  else return FALSE;        // 当前指针所指后继元素大于 e
 } // LocateElem

void InsAfter ( LinkList &L, SLink s )
 {
  // 在有序链表L中当前指针所指结点之后插入一个新的结点 *s,
  // 并移动当前指针指向新插入的结点。
  L.curPtr -> next = s;
  if ( L.tail == L.curPtr )
   L.tail = s;       // 若新结点插入在尾结点之后,则修改尾指针
  L.curPtr = s; ++L.curPos; // 移动当前指针
  ++L.length;        // 表长增 1
 }

  bool DelAfter( LinkList &L, ElemType& e )
 {
 // 若当前指针所指非单链表L中最后一个结点,
 // 则删除当前指针所指结点之后的结点,以 e 带回它的数据元素
 // 并返回 TRUE,否则不进行删除操作且返回 FALSE。
//若当前指针已经指向最后一个结点,它没有后继,因此不能进行删除。
  if ( L.curPtr == L.tail )
   return FALSE;
  p = L.curPtr -> next; e = p -> data;
  L.curPtr -> next = p -> next;       // 修改当前结点的指针
  if ( L.tail == p )
   L.tail = L.curPtr;           // 删除尾结点时修改尾指针
  delete p;                // 释放被删结点
  --L.length;               // 表长减1
  return TRUE;
 } // DelAfter

  void union ( OrderLinkList A, OrderLinkList B, OrderLinkList &C )
 {
  // 已知有序链表 A 和 B 分别表示两个集合,
  // 本算法求得有序链表 C 中所含元素是 A 和 B 的并集
  if ( InitList(C) )              // 初始化建空表
  {
   m = ListLength(A); n = Listlength(B);   // 分别求得表长
   i = 1; j = 1;
   while ( i <= m || j <= n )        // 顺序考察表中元素
   { 
    if ( GetPos(A,i) && GetPos(B,j) )
    {                 // 两个表中都还有元素未曾考察到
      GetCurElem(A,ea); GetCurElem(B,eb );
      if ( ea <= eb )
      {                 // 插入和 相同的元素
       if ( !MakeNode( s,ea ) ) exit(1);
       ++i;
       if ( ea == eb )
       ++j;              // 舍弃B表中相同元素
      }
     else
     {                  // 插入和 相同的元素
      if ( !MakeNode( s,eb ) ) exit(1);
      ++j;
     }
     }//if
    else if ( GetPos(A,i) )        // A表中尚有元素未曾插入
    {
     GetCurElem( A,ea );
     if ( !MakeNode( s,ea ) ) exit(1);
     ++i;
    }//else
    else                 // B表中尚有元素未曾插入
    {
     GetCurElem( B,eb );
     if ( !MakeNode( s,eb ) ) exit(1);
     ++j;
    }//else
    InsAfter(C,s);             // 插入到C表
  }
 } // union

void Intersection (OrderLinkList A,
            OrderLinkList B, OrderLinkList &C)
 {
  // 已知有序链表 A 和 B 分别表示两个集合,
  // 本算法求得有序链表 C 中所含元素是 A 和 B 的交集
  if ( InitList(C) )          // 初始化建空表
  {
   m = ListLength(A); n = Listlength(B); // 分别求得表长
   i = 1; j = 1;
   while ( i <= m && j <= n )     // 顺序考察表中元素
   {
    if ( GetPos(A,i) && GetPos(B,j) )
    {                // 两个表中都还有元素未曾考察
     GetCurElem( A,ea ); GetCurElem( B,eb );
     if ( ea < eb ) ++i;
     else if ( ea > eb ) ++j;
     else
     {                 // 插入和 相同的元素
      if ( !MakeNode( s,ea ) ) exit(1);
      ++i;++j;
      InsAfter(C,s);
     } // else
    } // if
   } // while
  } // if
 } // Intersection

搜索更多相关主题的帖子: 链表 结点 struct 结构 定义 
2006-04-30 16:32
小坦克
Rank: 1
等 级:新手上路
帖 子:4
专家分:0
注 册:2007-7-14
收藏
得分:0 

这位朋友,能不能给个具体点的程序源代码!这儿先谢谢了!

2007-07-14 09:46
尼尼章鱼
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2011-9-6
收藏
得分:0 
请问有没有具体的关于有序表中实现B中有的元素从A删除的算法吗(A-B)?我非常急啊。。。明天考试,请问你能不能写给我……
2012-01-10 21:47
快速回复:用有序表表示集合并实现集合的并、交、差三种操作
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.027249 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved