实际应用中带头节点的线性链表
2016-07-12 20:48
183 查看
/*========带头节点的线性链表类型=========*/ typedef char ElemType //结点类型 typedef struct LNode { char data; struct LNode *next; }*Link,*Position; //链表类型 typedef struct { Link head,tail; int len; }LinkList; /*======================================================*/ /*=======一些在其他函数定义中会调用的函数===============*/ /*======================================================*/ /*---compare---比较两个元素的大小关系*/ int Compare(char a,char b) { return a-b; } /*---visit---*/ int Visit(Link p) { if(...) return 1; else return 0; } /*---length---求链的长度*/ int Length(Link s) { int i=0; Link p=NULL; p=s; while(p->next!=NULL) { p=p->next; i++; } return i; } /*---print---在屏幕上输出链表的所有元素*/ void Print(LinkList L) { Link p=NULL; p=L.head; if(!p->next) { printf("\nThe LinkList is empty.\n\n"); return ; } printf("The List:"); while(p) { printf("%c-",p->data); p=p->next; } } /*======================================================*/ /*==========对带头结点的单链线性表进行操作的函数的定义==*/ /*======================================================*/ /*---分配由p指向的结点并赋值为e---*/ Position MakeNode(ElemType e) { Link p=NULL; p=(Link)malloc(sizeof(struct LNode)); if(p) { p->data=e; p->next=NULL; } else return; return p; } /*---释放p所指向的结点-*/ void FreeNode(Link p) { free(p); } /*---构造一个由L指向的空的线性表-*/ void InitList(LinkList *L) { L->head=MakeNode('L');//生成头结点 L->head->next=NULL;/*不是l->head=NULL*/ L->tail=L->head; L->len=0; } /*----------销毁由L指向的线性表---------*/ void DestroyList(LinkList *L) { Link p; p=(*L).tail; while(p!=(*L).head) { p=PriorPos(*L,p); FreeNode(p->next); } FreeNode((*L).head); } /*将线性表L置为空表,并释放原链表的头结点*/ void ClearList(LinkList *L) { Link p; p=(*L).tail; while(p!=(*L).head) { p=PriorPos(*L,p); FreeNode(p->next); } FreeNode((*L).head); } /*---将s指向的结点插入线性链表的第一个结点之前-*/ void InsFirst(LinkList *L,Link s) { s->next=L->head->next; if(!L->head->next) L->tail=s; /*当向一个空的线性表执行该操作时*/ L->head->next=s; L->len++; } /*---删除表中第一个结点并以q返回-*/ void DelFirst(LinkList *L,Link q) { if(!L->head->next) { printf("\nThe LinkList is empty,can not delete..\n"); return 0; } q=L->head->next; L->head->next=L->head->next->next; } /*---将指针s所的一串结点链接在线性表L的最后一个结点-*/ void Append(LinkList *L,Link s) { Link q; q=L->head; if(!L->tail) {/*考虑到链表为空的情况*/ L->head->next=s; while(q->next) q=q->next;/*尾结点的处理*/ L->tail=q; } L->tail->next=q=s; while(q->next) q=q->next;/*不能忘了对尾结点的处理*/ L->tail=q; L->len+=Length(s); } /*---删除线性表l中的尾结点-*/ void Remove(LinkList *L,Link q) { if(!L->tail) { printf("\nthe LinkList is empty,can not remonde..\n"); return 0; } q=L->tail; L->tail=PriorPos(*L,q); L->tail->next=NULL; } /*---将s所指向结点插入在p所指结点之前-*/ void InsBefore(LinkList *L,Link p,Link s) { Link q; q=PriorPos(*L,p); s->next=p; q->next=s; } /*---将s所指向结点插入在p所指结点之后-*/ void InsAfter(LinkList *L,Link p,Link s) { s->next=p->next; p->next=s; } /*---用e更新p所指向的当前结点-*/ void SetCurElem(Link p,ElemType e) { p->data=e; } /*---返回p所指结点中元素的值-*/ ElemType GetCurElem(Link p) { return p->data; } int Listempty(LinkList L) { /*---若线性表为空表则返回1,否则返回0-*/ if(L.head==L.tail) return 1; return 0; } int Listlength(LinkList L) { /*---返回线性表中元素个数-*/ return L.len; } Position GetHead(LinkList L) { /*---返回线性表l中头结点的位置-*/ return L.head; } Position GetLast(LinkList L) { /*-----返回线性表l中最后一个结点的位置-------*/ return L.tail; } /*---返回p所指结点的直接前驱的位置-*/ Position PriorPos(LinkList L,Link p) { Link q; q=L.head; if(q->next==p) return 0; while(q->next!=p) q=q->next; return q; } /*-----返回p所指结点的直接后继的位置-------*/ Position NextPos(Link p) { Link q; q=p->next; return q; } /*-----用p返回线性表l中第i个结点的位置,并返回ok-------*/ void LocatePos(LinkList L,int i,Link p) { p=L.head; if(i<=0||i>Listlength(L)) return 0; while(i) { p=p->next; i--; } } /*----返回表中第一个与e满足一定函数关系的结点次序位置----*/ int LocatElem(LinkList L,ElemType e) { int i=0; Link p; p=L.head->next; while(compare(p->data,e)&&p) { p=p->next; ++i; } if(!p) {/*考虑到查找不到指定元素的情况*/ printf("\nthere's no '%c' in this LinkList.",e); return 0; } return i; } /*----用一个函数遍历表中所有结点-------*/ void ListTraverse(LinkList L) { Link p; p=L.head; while(!visit(p)) p=p->next; }
将单链线性表La和Lb的元素按值非递减排列
Status MergeList_L(NLinkList &La, NLinkList &Lb, NLinkList &Lc,
int (*compare)(ElemType, ElemType))
{
// 算法2.21
// 已知单链线性表La和Lb的元素按值非递减排列。
// 归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列。
NLink ha, hb;
Position pa, pb, q;
ElemType a, b;
if (!InitList(Lc))
return ERROR; // 存储空间分配失败
ha = GetHead(La); // ha和hb分别指向La和Lb的头结点
hb = GetHead(Lb);
pa = NextPos(La, ha); // pa和pb分别指向La和Lb中当前结点
pb = NextPos(Lb, hb);
while (pa && pb)
{ // La和Lb均非空
a = GetCurElem(pa); // a和b为两表中当前比较元素
b = GetCurElem(pb);
if ((*compare)(a, b)<=0)
{ // a≤b
DelFirst(ha, q); Append(Lc, q); pa = NextPos(La, pa);
}
else
{ // a>b
DelFirst(hb, q); Append(Lc, q); pb = NextPos(Lb, pb);
}
} // while
if (pa)
Append(Lc, pa); // 链接La中剩余结点
else
Append(Lc, pb); // 链接Lb中剩余结点
FreeNode(ha);
FreeNode(hb); // 释放La和Lb的头结点
return OK;
} // MergeList_L
相关文章推荐
- MongoDB实战优化
- noip 2013 提高组 Day2 部分题解
- C - L1(大数比较)
- leetcode368. Largest Divisible Subset
- ToastUtil,一个阻止重复吐司并可控制位置的工具类
- Wildcard Matching
- http://www.cnbc.com/2016/07/12/tensions-in-south-china-sea-to-persist-even-after-court-ruling.html
- http://www.cnbc.com/2016/07/12/tensions-in-south-china-sea-to-persist-even-after-court-ruling.html
- nginx+keepalived构建高可用服务
- 跨海汇简介
- Kali linux安装漏洞扫描工具Nessus指南
- HashTable
- PHP入门学习——PHP语法
- Redhat上的DHCP配置实例
- **PYTHON** 函数
- 二叉树(Binary Tree)
- 基于.net平台常用的框架整理(转载)
- z-index 所遇问题
- MongoDB线上事故案例分享
- 在Ubuntu 14.04 安装 MySQL