您的位置:首页 > 理论基础 > 数据结构算法

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

2012-10-10 20:35 405 查看
2012-09-22 16:46:15 冒泡排序

// 普通的冒泡排序
void bubble_sort(int a[], int n)
{
int temp;
for(int j=n-1; j>0; j--)
{
for(int i=0; i<j; i++)
{
if(a[i] > a[i+1])
{
temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
}
}
}
}
// bubble_sort冒泡排序改进
void bubble_sort(int a[], int n)
{
// 将a中整数序列重新排列成自小至大有序的整数序列
for(i=n-1, change=TRUE; i>=1 && change; --i)    // 比较n-1轮,每轮比较i次
{
change = FALSE;
for(j=0; j<i; ++j)
{
if(a[j]>a[j+1]) {a[j]<-->a[j+1]; change=TRUE;}
}
// 如果该轮没有一次交换操作,那么表明已经为正序排列,直接退出算法
}
}


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

//简单的字符输入技巧
#include <iostream>
#include <cctype>
using namespace std;

int main()
{
char ch;
while(cin>>ch && toupper(ch) != 'Q')
{
//循环删除输入行中剩余部分
while(cin.get()!='\n')
{
continue;
}
//判断ch是否是字母
if(!isalpha(ch))
{
cout<<'\a';
continue;
}
cout<<ch<<endl;
}
return 0;
}


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

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


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

void MergeList(List &La, List &Lb, List &Lc) // 时间复杂度O(ListLength(LA)+ListLength(LB))
{
// 已知线性表La和Lb中的数据元素按值非递减排列
// 归并La和Lb得到新的下线性表Lc,Lc的数据元素也按值非递减排列
InitList(Lc);
i=j=1;
k=0;
La_len = ListLength(La);
Lb_len = ListLength(Lb);
while((i<=La_len)&&(j<=Lb_len))
{
// La和Lb均非空
GetElem(La, i, ai);
GetElem(Lb, j, bj);
if(ai<=bj)
{
ListInsert(Lc, ++k, ai);
++i;
}
else
{
ListInsert(Lc, ++k, bj);
++j;
}
}
while(i<=La_len)
{
GetElem(La, i++, ai);
ListInsert(Lc, ++k, ai);
}
while(j<=Lb_len)
{
GetElem(Lb, j++, bi);
ListInsert(Lc, ++k, bi);
}
}// MergeList 算法 2.2






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

// - - - - - 线性表的动态分配顺序存储结构 - - - - -
#define LIST_INIT_SIZE 100    // 线性表存储空间的初始分配量
#define LISTCREMENT    10    // 线性表存储空间的分配增量
typedef struct
{
ElemType *elem;    // 存储空间基址
int length;    // 当前长度
int listsize;    // 当前分配的存储容量(以sizeof(ElemType)为单位)
}SqList

Status InitList_Sq(SqList &L)
{
// 构造一个空的线性表L.
L.elem = (ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
if(!L.elem)
{
exit(OVERFLOW);
}
L.length = 0;    // 空表长度为0
L.listsize = LIST_INIT_SIZE;    // 初始存储容量
return OK;
}// InistList_Sq

Status ListInsert_Sq(SqList &L, int i, ElemType e)
{
// 在顺序线性表L中的第i个位置之前插入新的元素e,
// i的合法值为1<=i<=ListLength_Sq(L)+1
if(i<1 || i>L.length+1)
{
return ERROR;    // i值不合法
}
if(L.length >= L.listsize)    // 当前存储空间已满,增加分配
{
newbase = (ElemType*)realloc(L.elem, (L.listsize+LISTCREMENT)*sizeof(ElemType));
if(!newbase)
{
exit(OVERFLOW);    // 存储分配失败
}
L.elem = newbase;    // 新基址
L.listsize += LISTCREMENT;    // 增加存储容量
}
q = &(L.elem[i-1]);
for(p= &(L.elem[L.length-1]); p>=q; p--)    // 这边初值不应该为 p= &(L.elem[L.length])吗?
{
*(p+1) = *p;
}
*q = e;
++L.length;
return OK;
}// ListInsert_Sq






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

Status ListDelete_Sq(SqList &L, int i, ElemType &e)
{
// 在顺序线性表L中删除第i个元素,并用e返回其值
// i的合法值为1<=i<=ListLength_Sq(L)
if((i<1) || (i>L.length))
{
return ERROR;
}
p = &(L.elem[i-1]);    // p为被删除元素的位置
e = *p;    // 被删除元素的值赋给e
q = L.elem + L.length -1;    // 表尾元素的位置
for(++p; p<=1; ++p)    // 被删除元素之后的元素左移
{
*(p-1) = *p;
}
--L.length;    // 表长减1
return OK;
}// ListDelete_Sq

int LocateElem_Sq(SqList L, ElemType e, Status (*compare)(ElemType, ElemType))
{
// 在顺序线性表L中查找第1个值与e满足compare()的元素的位序
// 若找到,则返回其在L中的位序,否则返回0
i=1;
p=L.elem;
while(i<=L.length && !(*compare)(*p++, e))
{
++i;
}
if(i<=L.length)
{
return i;
}
else
{
return 0;
}
}// LocateElem_Sq


void MergeList_Sq(SqList La, SqList Lb, SqList &Lc) {  // 算法2.7
// 已知顺序线性表La和Lb的元素按值非递减排列。
// 归并La和Lb得到新的顺序线性表Lc,Lc的元素也按值非递减排列。
ElemType *pa,*pb,*pc,*pa_last,*pb_last;
pa = La.elem;  pb = Lb.elem;
Lc.listsize = Lc.length = La.length+Lb.length;
pc = Lc.elem = (ElemType *)malloc(Lc.listsize*sizeof(ElemType));
if (!Lc.elem)
exit(OVERFLOW);   // 存储分配失败
pa_last = La.elem+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++;      // 插入La的剩余元素
while (pb <= pb_last) *pc++ = *pb++;      // 插入Lb的剩余元素
} // MergeList


1// - - - - 线性表的单链表存储结构 - - - -
typedef struct LNode
{
     ElemType data;
struct LNode *next;
}LNode, *LinkList;
Status GetElem_L(LinkList &L,int i, ElemType &e) {  // 算法2.8
// L为带头结点的单链表的头指针。
// 当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR
LinkList p;
p = L->next;
int j = 1;           // 初始化,p指向第一个结点,j为计数器
while (p && j<i) {   // 顺指针向后查找,直到p指向第i个元素或p为空
p = p->next;  ++j;
}
if ( !p || j>i ) return ERROR;  // 第i个元素不存在
e = p->data;   // 取第i个元素
return OK;
} // GetElem_L


Status ListInsert_L(LinkList &L, int i, ElemType e) {  // 算法2.9
// 在带头结点的单链线性表L的第i个元素之前插入元素e
LinkList p,s;
p = L;
int j = 0;
while (p && j < i-1) {  // 寻找第i-1个结点
p = p->next;
++j;
}
if (!p || j > i-1) return ERROR;      // i小于1或者大于表长
s = (LinkList)malloc(sizeof(LNode));  // 生成新结点
s->data = e;  s->next = p->next;      // 插入L中
p->next = s;
return OK;
} // 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


void CreateList_L(LinkList &L, int n) {  // 算法2.11
// 逆位序输入(随机产生)n个元素的值,建立带表头结点的单链线性表L
LinkList p;
int i;
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;              // 先建立一个带头结点的单链表
for (i=n; i>0; --i) {
p = (LinkList)malloc(sizeof(LNode));  // 生成新结点
p->data = random(200);     // 改为一个随机生成的数字(200以内)
p->next = L->next;    L->next = p;    // 插入到表头
}
} // CreateList_L


void MergeList_L(LinkList &La, LinkList &Lb, LinkList &Lc) {
// 算法2.12
// 已知单链线性表La和Lb的元素按值非递减排列。
// 归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列。
LinkList pa, pb, pc;
pa = La->next;    pb = Lb->next;
Lc = pc = La;             // 用La的头结点作为Lc的头结点
while (pa && pb) {
if (pa->data <= pb->data) {
pc->next = pa;   pc = pa;   pa = pa->next;
}
else { pc->next = pb;   pc = pb;   pb = pb->next; }
}
pc->next = pa ? pa : pb;  // 插入剩余段
free(Lb);                 // 释放Lb的头结点
} // MergeList_L




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

// - - - - 线性表的静态单链表存储结构 - - - -
#define MAXSIZE 1000    // 链表的最大长度
typedef stuct
{
ElemType data;
int cur;
}component, SLinkList[MAXSIZE];

int LocateElem_SL(SLinkList S, ElemType e)
{
// 在静态单链线性表L中查找第1个值为e的元素
// 若找到,则返回它在L中的位序,否则返回0
i = S[0].cur;    // i指示表中第一个结点
while(i&&S[i].data != e)
{
i = S[i].cur;
}
return i;
}// LocateElem_SL

void InitSpace_SL(SLinkList &space)
{
// 将一位数组space中个分量链成一个备用链表,space[0].cur为头指针,
// “0”表示空指针
for(i=0; i<MAXSIZE-1; i++)
{
space[i].cur = i+1;
}
space[MAXSIZE-1].cur = 0;
}// InitSpace_SL

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




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

void difference(SLinkList &space, int &S) {  // 算法2.17
// 依次输入集合A和B的元素,在一维数组space中建立表示集合(A-B)∪(B-A)
// 的静态链表, S为头指针。假设备用空间足够大,space[0].cur为头指针。
InitSpace_SL(space);          // 初始化备用空间
S = Malloc_SL(space);         // 生成S的头结点
r = S;                        // r指向S的当前最后结点
scanf(m, n);                  // 输入A的元素个数
for (j=1; j<=m; ++j) {        // 建立集合A的链表
i = Malloc_SL(space);      // 分配结点
scanf(space[i].data);   // 输入A的元素值
space[r].cur = i;  r = i;  // 插入到表尾
}
space[r].cur = 0;             // 尾结点的指针为空
for (j=1; j<=n; ++j) {
// 依次输入B的元素,若不在当前表中,则插入,否则删除
scanf(b);       // 输入B的元素值
p = S;   k = space[S].cur;  // k指向集合A中第一个结点
while (k!=space[r].cur && space[k].data!=b) {// 在当前表中查找
p = k;    k = space[k].cur;
}
if (k == space[r].cur) {
// 当前表中不存在该元素,插入在r所指结点之后,且r的位置不变
i = Malloc_SL(space);
space[i].data = b;
space[i].cur = space[r].cur;
space[r].cur = i;
} else {                     // 该元素已在表中,删除之
space[p].cur = space[k].cur;
Free_SL(space, k);
if (r == k)  r = p;      // 若删除的是尾元素,则需修改尾指针
}
}
} // difference


DuLinkList GetElemP_DuL(DuLinkList va, int i) {
// L为带头结点的双向循环线性表的头指针。
// 当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR
DuLinkList p;
p = va->next;
int j = 1;  // 初始化,p指向第一个结点,j为计数器
while (p!=va && j<i) { //顺指针向后查找,直到p指向第i个元素或p为空
p = p->next;
++j;
}
if (p==va && j<i) return NULL;  // 第i个元素不存在
else return p;
} // GetElem_L

Status ListInsert_DuL(DuLinkList &L, int i, ElemType e) { //算法2.18
// 在带头结点的双链循环线性表L的第i个元素之前插入元素e,
// i的合法值为1≤i≤表长+1。
DuLinkList p,s;
if (!(p = GetElemP_DuL(L, i)))  // 在L中确定第i个元素的位置指针p
return ERROR;                 // p=NULL, 即第i个元素不存在
if (!(s = (DuLinkList)malloc(sizeof(DuLNode))))
return ERROR;
s->data = e;
s->prior = p->prior;
p->prior->next = s;
s->next = p;
p->prior = s;
return OK;
} // ListInsert_DuL


Status ListDelete_DuL(DuLinkList &L, int i, ElemType &e) {//算法2.19
// 删除带头结点的双链循环线性表L的第i个元素,i的合法值为1≤i≤表长
DuLinkList p;
if (!(p = GetElemP_DuL(L, i)))  // 在L中确定第i个元素的位置指针p
return ERROR;                 // p=NULL, 即第i个元素不存在
e = p->data;
p->prior->next = p->next;
p->next->prior = p->prior;
free(p);
return OK;
} // ListDelete_DuL
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: