顯示具有 資料結構 標籤的文章。 顯示所有文章
顯示具有 資料結構 標籤的文章。 顯示所有文章

2013年1月15日 星期二

資料結構(8)


第八章 Graphs and Their Applications

8.1 Graphs

A graph consists of a set of nodes(or vertices) and a set of arcs(or edges). Each arc in a graph is specified by a pair of nodes.











Note that a graph need not to be a tree, but that a tree must br a graph.

A node n is incedent to an arc x if n is one of the two nodes in the ordered pair of nodes that constitute x. The degree of a node is the number of arcs incident to it.

The indegree of a node n is the number of arcs that have n as the head, and the outdegree of n is the number of arcs that have n as the tail.









Such a graph, in which a number is associated with each arc, is called a weighted graph or a network. The number associated with an arc is called its weight.

A path from a node to itself is called a cycle.
#define MAXNODES 50

struct node{
/*information associated with each node*/
};

struct arc{
int adj;
/*information associated with each arc*/
};

struct graph{
struct node nodes[MAXNODES];
struct arc arcs[MAXNODES][MAXNODES]
};
struct graph g;

void join(int adj[][MAXNODES], int node1, int node2)
{
/* add an arc from node1 to node2*/
adj[node1][node2]=TRUE;
}
void remv(int adj[][MAXNODES], int node1, int node2)
{
/* delete an arc from node1 to node2*/
adj[node1][node2]=FALSE;
}
int adjacent(int adj[][MAXNODES], int node1, int node2)
{
return ((adj[node1][node2]==TRUE)?TRUE:FALSE);
}
Transitive Closure
Its value is TRUE if and only if the values of both adj[i][k] and adj[k][j] are TRUE, which implies that there is an arc from node I to node k and an arc from node k to node j.

path0[i][j]=adj, since the only way to go from node I to node j without passing through any other nodes is to go directly from I to j.

void transclose(int adj[][MAXNODES], int path[][MAXNODES])
{
int I,j,k;
for(i=0;i<MAXNODES;++i)
for(j=0;j<MAXNODES;++j)
path[i][j]=adj[i][j];
for(k=0;i<MAXNODES;++k)
for(i=0;j<MAXNODES;++i)
if(path[i][k]==TRUE)
for(j=0;j<MAXNODES;++j)
path[i][j]=path[i][j]||path[k][j];

}

Page 527 Shortest-Path Algorithm

Spanning Forests

A forest may be defined as an acyclic graph on which every node has one or no predecessors.

資料結構(9)


第九章 Storage Management

A list is simply a sequence of objects called elements. Associated with each list element is a value.

q=nullelt;
p=first(list);
while(p!=nullelt)
{
if(info(p)=='w')
{
/*remode node(p) from the list*/
p=next(p);
if(q == nullelt)
setnext(q,p);
}
else
{
p=q;
p=next(p);
}
}



#define INTGR 1
#define CH 2
#define LST 3

struct nodetype{
int utype;
union{
int intgrinfo;
char charinfo;
struct nodetype *listinfo;
} info;
struct nodetype *next;
};
typedef struct nodetype *NODEPTR;

NODEPTR tail(NODEPTR list)
{
if(list==NULL)
{
printf(“illegal tail operation”);
exit(1);
}
else
return list->next;
}
struct {
int utype;
union{
int intgrinfo;
char charinfo;
struct nodetype *listinfo;
} info;
} infotype;
typedef struct infotype *INFOPTR;
void head(NODEPTR list,INFOPTR pitem)
{
if(list==NULL)
{
printf(“illegal head operation”);
exit(1);
}
pitem = (INFOPTR) malloc (sizeof(struct infotype));
pitem->utype=list->utype;
pitem->info=list->info;
return;
}
NODEPTR addon(NODEPTR list,struct infotype *pitem)
{
NODEPTR newptr;

newptr=(INFOPTR)malloc(sizeof(struct nodetype));
newptr->utype=pitem->utype;
newptr->info = pitem->info;
newptr->next=list;
return newptr;
}
void settail(NODEPTR *plist,NODEPTR t1)
{
NODEPTR p;
p=*plist->next;
*plist->next=t1;
freelist(p);
}

Reference Count Method

Under this method each node has an additional count field that keeps a count (called the reference count) of the number of pointers(both internal and external) to that node.

Collection and Compaction

for(i=1;i<MAXNODES;i++)
{
node[i].header=0;
node[i].headptr='N';
node[i].infoptr='N';
node[i].nextptr='N';

}

newloc=0;
for(nd=1;nd<MAXNODES;nd++)
if(node[nd].mark==TRUE)
newloc++;

p=node[nd].header;
source = node[nd].headptr;

while(p!=0)
if(source=='I')
{
q=node[p].lstinfo;
source=node[p].infoptr;
node[p].lstinfo=newloc;
node[p].infoptr='N';
p=q;
}
else
{
q=node[p].next;
source=node[p].nextptr;
node[p].next=newloc;
node[p].nextptr='N';
p=q;
}
node[nd].headptr='N';
node[nd].header=0;

if((node[nd].utype==LST)&&(node[nd].lstinfo!=0))
{
p=node[nd].lstinfo;
node[nd].lstinfo=node[p].header;
node[nd].infoptr=node[p].headptr;
node[p].header=nd;
node[p].headptr='I';
}
p=node[nd].next;
node[nd].next=node[p].header;
node[nd].nextptr=node[p].headptr;
if(p!=0)
{
node[p].header=nd;
[node[p].headptr='L';
}
}
newloc=0;
for(nd=1;nd<MAXNODES;nd++)
if(node[nd].mark)
{
newloc++;
p=node[nd].header;
source = node[nd].headptr;
while(p!=0)
if(source=='I')
{
q=node[p].lstinfo;
source=node[p].infoptr;
node[p].lstinfo=newloc;
node[p].infoptr ='N';
p=q;
}
else
{
q=node[p].next;
source=node[p].nextptr;
node[p].next=newloc;
node[p].nextptr ='N';
p=q;
}

node[nd].headptr='N';
node[nd].header=0;
node[nd].mark=false;
node[newloc]=node[nd];
}

2013年1月13日 星期日

資料结構(7)


第七章Searching

7.1 Basic Search Techniques

A table or a file is a group of elements, each of which is called a record. Associated with each record is a key, which is used to differentiate among different records.

In the simplest form, the key is contained within the record at a specific offset from the start of the record. Such a key is called an internal key or an embedded key.

For every file there is at least one set of keys that is unique. Such a key is called a primary key.

It will probably not be unique, since there may be two records with the same state in the file, such a key is called a secondary key.

A search algorithm is an algorithm that accepts an argument a and tries to find a record whose key is a.

A table of records in which a key is used for retrieval is often called a search table or as dictionary.

Dictionary as an abstract data type

typedef KEYTYPE ... /* a type of key*/
typedef RECTYPE … /* a type of record*/
RECTYPE nullrec=... /*a “null” record*/

KEYTYPE keyfunct(r)
RECTYPE r;
{…
};


abstract typedef [rectype] TABLE (RECTYPE);

abstract member(tbl,k)
TABLE(RECTYPE) tbl;
KEYTYPE k;
postcondition if(there exists an r in tbl such that keyfunct(r)==k)
then member = TRUE
else member = FALSE

abstract RECTYPE search(tbl,k)
TABLE(RECTYPE) tbl;
KEYTYPE k;
postcondition (not member(tbl,k)&& (search == nullrec)
|| (member(tbl,k) &&keyfunct(search)==k);

abstract insert(tbl,r)
TABLE(RECTYPE) tbl;
KEYTYPE r;
precondition member(tbl,keyfunct(r))==FALSE
postcondition insert(tbl,r);
(tbl-[r])==tbl'

abstract delete(tbl,k)
TABLE(RECTYPE) tbl;
KEYTYPE k;
postcondition tbl==(tbl'-[search(tbl,k)]);









Binary Search

The most efficient method of searching a sequential table without the use of auxiliary indices or table is the binary search.
O(logn)

low=0;
hi=n-1;
while(low<=hi)
{
mid=(low+hi)/2;
if(key==k(mid))
return mid;
if(key<k(mid))
hi=mid-1;
else
low=mid+1
}
return -1;

Interpolation Search
Another technique for searching an ordered array is called interpolation search. If the keys are uniformly distributed between k(0) and k(n-1)

O(loglogn)










Tree Searching
Inserting into a binary tree

q=null;
p=tree;
while(p!=null)
{
if(key==k(p))
return p;
q=p;
if(key<k(p))
p=left(p);
else
p=right(p);
}
v=maketree(rec,key);
if(q==null)
tree=v;
else
if(key<k(q))
left(q)=v;
else
right(q)=v;
return v;
Deleting from a binary search tree

q=null;
p=tree;
while(p!=null && k(p)!=key)
{
q=p;
p=(key<k(p)?left(p):right(p);
}
if(p==null)
return;

Balanced Trees

If the probability of searching for a key in a table is the same for all keys, a balanced tree yields the most efficient search.

/* Part I: search and inset into the binary tree*/
fp=null;
p=tree;
fya=null;
ya=p;
/* ya points the youngest ancestor whick may become unbalanced*/

while(p!=null)
{
if(key==k(p))
return p;
q= (key <k(p))? left(p):right(p);
if(q!=null)
if(bal(q)!=0)
{
fya=p;
ya=q;
}
fp=p;
p=q;
}
q=maketree(rec,key);
bal(q)=0;
(key<k(fp))?left(fp)=q:right(fp)=q;

p=(key<k(ya))?left(ya):right(ya);
s=p;
while(p!=q)
{
if(key<k(p))

{
bal(p)=1;
p=left(p);
}
else
{
bal(p)=-1;
p=right(p);
}
}

/*Part II:tree is unbalanced*/

imbal=(key<k(ya))?1:-1;
if(bal(ya)==0)
{
bal(ya)=imbal;
return q;
}
/* part III:rebalanced*/
if(bal(s)==imbal)
{
P=S;
if(imbal==-1)
rightrotation(ya);
else
leftrotation(ya);
bal(ya)=0;
bal(s)=0;
}
else
{
if(imbal==1)
{
p=right(s);
leftrotation(s);
left(ya)=p;
rightrotation(ya);
}
else
{
p=left(s);
right(ya)=p;
rightrotation(s);
leftrotation(ya);
}
if(bal(p)==0)
{
bal(ya)=0';
bal(s)=0;
}
else
{
if(bal(p)==imbal)
{
bal(ya)=-imbal;
bal(s)=0;
}
else
{
bal(ya)=0;
bal(s)=imbal;
}
}
bal(p)=0
}
if(fya==null)
tree=p;
else
ya=right(fya))?right(fya)=p:left(fya)=p;
return q;

A multiway search tree of order n is a general tree in which each node has n or fewer subtrees and contains one fewer key than it has subtrees.

p=tree;
if(p==null)
{
position = -1;
return -1;
}
i=nodesearch(p,key);
if(i<numtrees(p)-1&& key==k(p,i)
{
position=i;
return p;
}
return search(son(p,i));
====================================
p=tree;
while(p!=null)
{
i=nodesearch(p,key);
if(i<numtrees(p)-1&& key==k(p,i)
{
position=i;
return p;
}
p=son(p,i);
}
position = -1;
return -1;

traversing a multiway tree



if(tree !=null)
{
nt=numtrees(tree);
for(i=0;i<nt-1;i++)
{
traverse(son(tree,i);
printf(“%d”,k(tree,i));
}
traverse(son(tree,nt);
}

B+-Trees
One of the major drawbacks of the B-tree is the difficulty of traversing the key sequentially.

11.4 Hashing

A function that transforms a key into a table index is called a hash function. If h is a hash function and key is a key, h(key) is called the hash of key and is the index at which a record with the key should be placed.

#define TABLESIZE …
typedef KEYTYPE …
typedef RECTYPE …
struct record{
KEYTYPE k;
RECTYPE r;
} table[TABLESIZE];

int search(KEYTYPE key,RECTYPE rec)
{
int i;
i=h(key);
while(table[i].k!=key && table[i].k!=nullkey)
{
i=rh(i); //rehash
}
if(table[i].k==nullkey)
{
table[i].k=key;
table[i].r=rec;
}
return i;
}

struct nodetype *search(KEYTYPE key, RECTYPE rec)
{
struct nodetype *p,*q,*s;
i=h(key);
q=NULL;
p=bucket[i];
while(p!=NULL&&p->k!=key)
{
q=p;
p=p->next;
}
if(p->k==key)
return p;
s=getnode();
s->k=key;
s->r=rec;
s->next=NULL;
if(q==NULL)
bucket[i]=s;
else
q->next=s;
return s;
}


Perfect Hash Functions

Given a set of keys K={k1,k2,...,kn} a perfect hash function is a hash function h such that h(ki)!=h(kj) for all distinct i and j.

h(key)=((r+s*key)%x)d
remainder reduction perfect hash function.