博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

数据结构笔记C/C++——线性表

Posted on 2012-10-10 20:35  子水  阅读(357)  评论(0)    收藏  举报

2012-09-22 16:46:15 冒泡排序

 1 // 普通的冒泡排序 
 2 void bubble_sort(int a[], int n) 
 3 {
 4     int temp;
 5     for(int j=n-1; j>0; j--)
 6     {
 7         for(int i=0; i<j; i++)
 8         {
 9             if(a[i] > a[i+1])
10             {
11                 temp = a[i];
12                 a[i] = a[i+1];
13                 a[i+1] = temp;
14             }
15         }         
16     }
17 } 
18 // bubble_sort冒泡排序改进 
19 void bubble_sort(int a[], int n)
20 {
21     // 将a中整数序列重新排列成自小至大有序的整数序列
22     for(i=n-1, change=TRUE; i>=1 && change; --i)    // 比较n-1轮,每轮比较i次
23     {
24         change = FALSE;
25         for(j=0; j<i; ++j) 
26         {
27             if(a[j]>a[j+1]) {a[j]<-->a[j+1]; change=TRUE;}
28         }
29         // 如果该轮没有一次交换操作,那么表明已经为正序排列,直接退出算法 
30     }
31 }     

 2012-09-21 11:10:44 字符输入

 1 //简单的字符输入技巧 
 2  #include <iostream>
 3  #include <cctype> 
 4  using namespace std;
 5  
 6  int main()
 7  {
 8      char ch;
 9      while(cin>>ch && toupper(ch) != 'Q')
10      {
11          //循环删除输入行中剩余部分 
12          while(cin.get()!='\n')
13          {
14              continue;
15          }
16          //判断ch是否是字母 
17          if(!isalpha(ch))
18          {
19              cout<<'\a';
20              continue;
21          }
22          cout<<ch<<endl;
23      }
24      return 0;
25  }

 2012-09-30 10:18:22 集合的并集

 1 void union(List &La, List &Lb)    // 需要修改La,所以这里必须为引用或指针 
 2 {
 3     // 将素有在线性表Lb中但不在La中的数据元素插入到La中
 4     La_len = ListLength(La);
 5     Lb_len = ListLength(Lb);    // 求线性表的长度
 6     for(i=1; i<=Lb_len; i++)
 7     {
 8         GetElem(Lb, i, e);    // 取Lb中第i个数据元素赋给e
 9         if(!LocateElem(La, e, equal))
10         {
11             ListInsert(La, ++La_len, e);
12         }    // La中不存在和e相同的数据元素,则插入之
13     }
14 }// union 算法 2.1
15 // 时间复杂度O(ListLength(LA)xListLength(LB))         

2012-09-30 11:15:54 融合线性表

 1 void MergeList(List &La, List &Lb, List &Lc) // 时间复杂度O(ListLength(LA)+ListLength(LB)) 
 2 {
 3     // 已知线性表La和Lb中的数据元素按值非递减排列
 4     // 归并La和Lb得到新的下线性表Lc,Lc的数据元素也按值非递减排列 
 5     InitList(Lc);
 6     i=j=1;
 7     k=0;
 8     La_len = ListLength(La);
 9     Lb_len = ListLength(Lb);
10     while((i<=La_len)&&(j<=Lb_len))
11     {
12         // La和Lb均非空
13         GetElem(La, i, ai);
14         GetElem(Lb, j, bj);
15         if(ai<=bj)
16         {
17             ListInsert(Lc, ++k, ai);
18             ++i;
19         }
20         else
21         {
22             ListInsert(Lc, ++k, bj);
23             ++j;
24         }
25     }
26     while(i<=La_len)
27     {
28         GetElem(La, i++, ai);
29         ListInsert(Lc, ++k, ai);
30     } 
31     while(j<=Lb_len)
32     {
33         GetElem(Lb, j++, bi);
34         ListInsert(Lc, ++k, bi);
35     } 
36 }// MergeList 算法 2.2

 

 

2012-09-30 20:40:24 顺序线性表初始化,插入操作

 1 // - - - - - 线性表的动态分配顺序存储结构 - - - - -
 2 #define LIST_INIT_SIZE 100    // 线性表存储空间的初始分配量
 3 #define LISTCREMENT    10    // 线性表存储空间的分配增量
 4 typedef struct
 5 {
 6     ElemType *elem;    // 存储空间基址 
 7     int length;    // 当前长度 
 8     int listsize;    // 当前分配的存储容量(以sizeof(ElemType)为单位) 
 9 }SqList 
10 
11 Status InitList_Sq(SqList &L)
12 {
13     // 构造一个空的线性表L.
14     L.elem = (ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
15     if(!L.elem)
16     {
17         exit(OVERFLOW);
18     }
19     L.length = 0;    // 空表长度为0 
20     L.listsize = LIST_INIT_SIZE;    // 初始存储容量 
21     return OK;
22 }// InistList_Sq 
23 
24 Status ListInsert_Sq(SqList &L, int i, ElemType e)
25 {
26     // 在顺序线性表L中的第i个位置之前插入新的元素e,
27     // i的合法值为1<=i<=ListLength_Sq(L)+1
28     if(i<1 || i>L.length+1)
29     {
30         return ERROR;    // i值不合法 
31     } 
32     if(L.length >= L.listsize)    // 当前存储空间已满,增加分配 
33     {
34         newbase = (ElemType*)realloc(L.elem, (L.listsize+LISTCREMENT)*sizeof(ElemType)); 
35         if(!newbase)
36         {
37             exit(OVERFLOW);    // 存储分配失败 
38         }
39         L.elem = newbase;    // 新基址 
40         L.listsize += LISTCREMENT;    // 增加存储容量 
41     } 
42     q = &(L.elem[i-1]);
43     for(p= &(L.elem[L.length-1]); p>=q; p--)    // 这边初值不应该为 p= &(L.elem[L.length])吗? 
44     {
45         *(p+1) = *p;
46     }
47     *q = e;
48     ++L.length;
49     return OK;
50 }// ListInsert_Sq 

 

2012-10-10 14:08:12 顺序线性表删除操作,查找操作,合并操作。单链表存取、插入、删除、创建和合并操作

 1 Status ListDelete_Sq(SqList &L, int i, ElemType &e)
 2 {
 3     // 在顺序线性表L中删除第i个元素,并用e返回其值
 4     // i的合法值为1<=i<=ListLength_Sq(L)
 5     if((i<1) || (i>L.length))
 6     {
 7         return ERROR;
 8     }
 9     p = &(L.elem[i-1]);    // p为被删除元素的位置 
10     e = *p;    // 被删除元素的值赋给e 
11     q = L.elem + L.length -1;    // 表尾元素的位置 
12     for(++p; p<=1; ++p)    // 被删除元素之后的元素左移 
13     {
14         *(p-1) = *p;
15     } 
16     --L.length;    // 表长减1 
17     return OK;
18 }// ListDelete_Sq 
19 
20 int LocateElem_Sq(SqList L, ElemType e, Status (*compare)(ElemType, ElemType))
21 {
22     // 在顺序线性表L中查找第1个值与e满足compare()的元素的位序 
23     // 若找到,则返回其在L中的位序,否则返回0
24     i=1;
25     p=L.elem;
26     while(i<=L.length && !(*compare)(*p++, e))
27     {
28         ++i;
29     }
30     if(i<=L.length)
31     {
32         return i;
33     }
34     else
35     {
36         return 0;
37     }
38 }// LocateElem_Sq 
 1 void MergeList_Sq(SqList La, SqList Lb, SqList &Lc) {  // 算法2.7
 2   // 已知顺序线性表La和Lb的元素按值非递减排列。
 3   // 归并La和Lb得到新的顺序线性表Lc,Lc的元素也按值非递减排列。
 4   ElemType *pa,*pb,*pc,*pa_last,*pb_last;
 5   pa = La.elem;  pb = Lb.elem;
 6   Lc.listsize = Lc.length = La.length+Lb.length;
 7   pc = Lc.elem = (ElemType *)malloc(Lc.listsize*sizeof(ElemType));
 8   if (!Lc.elem)
 9     exit(OVERFLOW);   // 存储分配失败
10   pa_last = La.elem+La.length-1;
11   pb_last = Lb.elem+Lb.length-1;
12   while (pa <= pa_last && pb <= pb_last) {  // 归并
13     if (*pa <= *pb) *pc++ = *pa++;
14     else *pc++ = *pb++;
15   }
16   while (pa <= pa_last) *pc++ = *pa++;      // 插入La的剩余元素
17   while (pb <= pb_last) *pc++ = *pb++;      // 插入Lb的剩余元素
18 } // MergeList
 1// - - - - 线性表的单链表存储结构 - - - -
typedef struct LNode
{
   ElemType data;
struct LNode *next;
}LNode, *LinkList;
Status GetElem_L(LinkList &L,int i, ElemType &e) { // 算法2.8 2 // L为带头结点的单链表的头指针。 3 // 当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR 4 LinkList p; 5 p = L->next; 6 int j = 1; // 初始化,p指向第一个结点,j为计数器 7 while (p && j<i) { // 顺指针向后查找,直到p指向第i个元素或p为空 8 p = p->next; ++j; 9 } 10 if ( !p || j>i ) return ERROR; // 第i个元素不存在 11 e = p->data; // 取第i个元素 12 return OK; 13 } // GetElem_L
 1 Status ListInsert_L(LinkList &L, int i, ElemType e) {  // 算法2.9
 2   // 在带头结点的单链线性表L的第i个元素之前插入元素e
 3   LinkList p,s;
 4   p = L;   
 5   int j = 0;
 6   while (p && j < i-1) {  // 寻找第i-1个结点
 7     p = p->next;
 8     ++j;
 9   } 
10   if (!p || j > i-1) return ERROR;      // i小于1或者大于表长
11   s = (LinkList)malloc(sizeof(LNode));  // 生成新结点
12   s->data = e;  s->next = p->next;      // 插入L中
13   p->next = s;
14   return OK;
15 } // LinstInsert_L
Status ListDelete_L(LinkList &L, int i, ElemType &e) {  // 算法2.10
  // 在带头结点的单链线性表L中,删除第i个元素,并由e返回其值
  LinkList p,q;
  p = L;
  int j = 0;
  while (p->next && j < i-1) {  // 寻找第i个结点,并令p指向其前趋
    p = p->next;
    ++j;
  }
  if (!(p->next) || j > i-1) return ERROR;  // 删除位置不合理
  q = p->next;
  p->next = q->next;           // 删除并释放结点
  e = q->data;
  free(q);
  return OK;
} // ListDelete_L
 1 void CreateList_L(LinkList &L, int n) {  // 算法2.11
 2   // 逆位序输入(随机产生)n个元素的值,建立带表头结点的单链线性表L 
 3   LinkList p;
 4   int i;
 5   L = (LinkList)malloc(sizeof(LNode));
 6   L->next = NULL;              // 先建立一个带头结点的单链表
 7   for (i=n; i>0; --i) {
 8     p = (LinkList)malloc(sizeof(LNode));  // 生成新结点
 9     p->data = random(200);     // 改为一个随机生成的数字(200以内)
10     p->next = L->next;    L->next = p;    // 插入到表头
11   }
12 } // CreateList_L
 1 void MergeList_L(LinkList &La, LinkList &Lb, LinkList &Lc) {
 2   // 算法2.12
 3   // 已知单链线性表La和Lb的元素按值非递减排列。
 4   // 归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列。
 5   LinkList pa, pb, pc;
 6   pa = La->next;    pb = Lb->next;
 7   Lc = pc = La;             // 用La的头结点作为Lc的头结点
 8   while (pa && pb) {
 9     if (pa->data <= pb->data) {
10       pc->next = pa;   pc = pa;   pa = pa->next;
11     }
12     else { pc->next = pb;   pc = pb;   pb = pb->next; }
13   }
14   pc->next = pa ? pa : pb;  // 插入剩余段
15   free(Lb);                 // 释放Lb的头结点
16 } // MergeList_L

 

2012-10-10 19:54:23 静态链表的结构、初始化、定位等操作

 1 // - - - - 线性表的静态单链表存储结构 - - - -
 2 #define MAXSIZE 1000    // 链表的最大长度
 3 typedef stuct
 4 {
 5     ElemType data;
 6     int cur;
 7 }component, SLinkList[MAXSIZE]; 
 8 
 9 int LocateElem_SL(SLinkList S, ElemType e)
10 {
11     // 在静态单链线性表L中查找第1个值为e的元素
12     // 若找到,则返回它在L中的位序,否则返回0
13     i = S[0].cur;    // i指示表中第一个结点
14     while(i&&S[i].data != e)
15     {
16         i = S[i].cur; 
17     }
18     return i;
19 }// LocateElem_SL 
20 void InitSpace_SL(SLinkList &space) 21 { 22 // 将一位数组space中个分量链成一个备用链表,space[0].cur为头指针, 23 // “0”表示空指针 24 for(i=0; i<MAXSIZE-1; i++) 25 { 26 space[i].cur = i+1; 27 } 28 space[MAXSIZE-1].cur = 0; 29 }// InitSpace_SL

30 int Malloc_SL(SLinkList &space) { // 算法2.15 31 // 若备用空间链表非空,则返回分配的结点下标,否则返回0 32 int i = space[0].cur; 33 if (space[0].cur) space[0].cur = space[i].cur; 34 return i; 35 } // Malloc_SL

 

2012-10-11 09:33:36 (A-B)∪(B-A) 循环链表 双向链表 双向循环链表

 1 void difference(SLinkList &space, int &S) {  // 算法2.17
 2   // 依次输入集合A和B的元素,在一维数组space中建立表示集合(A-B)∪(B-A)
 3   // 的静态链表, S为头指针。假设备用空间足够大,space[0].cur为头指针。
 4   InitSpace_SL(space);          // 初始化备用空间
 5   S = Malloc_SL(space);         // 生成S的头结点
 6   r = S;                        // r指向S的当前最后结点
 7   scanf(m, n);                  // 输入A的元素个数
 8   for (j=1; j<=m; ++j) {        // 建立集合A的链表
 9     i = Malloc_SL(space);      // 分配结点
10     scanf(space[i].data);   // 输入A的元素值
11     space[r].cur = i;  r = i;  // 插入到表尾
12   }
13   space[r].cur = 0;             // 尾结点的指针为空
14   for (j=1; j<=n; ++j) {
15     // 依次输入B的元素,若不在当前表中,则插入,否则删除
16     scanf(b);       // 输入B的元素值
17     p = S;   k = space[S].cur;  // k指向集合A中第一个结点
18     while (k!=space[r].cur && space[k].data!=b) {// 在当前表中查找
19       p = k;    k = space[k].cur;
20     }
21     if (k == space[r].cur) {
22       // 当前表中不存在该元素,插入在r所指结点之后,且r的位置不变
23       i = Malloc_SL(space);
24       space[i].data = b;
25       space[i].cur = space[r].cur;
26       space[r].cur = i;
27     } else {                     // 该元素已在表中,删除之
28       space[p].cur = space[k].cur;
29       Free_SL(space, k);
30       if (r == k)  r = p;      // 若删除的是尾元素,则需修改尾指针
31     }
32   }
33 } // difference
 1 DuLinkList GetElemP_DuL(DuLinkList va, int i) {  
 2   // L为带头结点的双向循环线性表的头指针。
 3   // 当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR
 4   DuLinkList p;
 5   p = va->next;   
 6   int j = 1;  // 初始化,p指向第一个结点,j为计数器
 7   while (p!=va && j<i) { //顺指针向后查找,直到p指向第i个元素或p为空
 8     p = p->next;
 9     ++j;
10   }
11   if (p==va && j<i) return NULL;  // 第i个元素不存在
12   else return p;
13 } // GetElem_L
14 
15 Status ListInsert_DuL(DuLinkList &L, int i, ElemType e) { //算法2.18
16   // 在带头结点的双链循环线性表L的第i个元素之前插入元素e,
17   // i的合法值为1≤i≤表长+1。
18   DuLinkList p,s;
19   if (!(p = GetElemP_DuL(L, i)))  // 在L中确定第i个元素的位置指针p
20     return ERROR;                 // p=NULL, 即第i个元素不存在
21   if (!(s = (DuLinkList)malloc(sizeof(DuLNode))))
22     return ERROR;
23   s->data = e;
24   s->prior = p->prior;
25   p->prior->next = s;
26   s->next = p;
27   p->prior = s;
28   return OK;
29 } // ListInsert_DuL
 1 Status ListDelete_DuL(DuLinkList &L, int i, ElemType &e) {//算法2.19
 2   // 删除带头结点的双链循环线性表L的第i个元素,i的合法值为1≤i≤表长
 3   DuLinkList p;
 4   if (!(p = GetElemP_DuL(L, i)))  // 在L中确定第i个元素的位置指针p
 5     return ERROR;                 // p=NULL, 即第i个元素不存在
 6   e = p->data;
 7   p->prior->next = p->next;
 8   p->next->prior = p->prior;
 9   free(p);    
10   return OK;
11 } // ListDelete_DuL