typedef struct LNode
{
ElemType data;
LNode *next;
}*Link,*Position;
struct LinkList
{
Link head, tail;//分别指向线性链表中的头结点和最后一个结点
int len;//指示线性链表中数据元素的个数
};
void MakeNode(Link &p, ElemType &e)
{
//分配由p指向的值为e的结点。若分配失败,则退出
p = (Link)malloc(sizeof(LNode));
if (!p)
{
exit(ERROR);
}
p->data = e;
}
void FreeNode(Link &p)
{
//释放p所指结点
free(p);
p = NULL;
}
void InitList(LinkList &L)
{
//构造一个空的线性链表L
Link p;
p = (Link)malloc(sizeof(LNode));//生成头结点
if (p)
{
p->next = NULL;
L.head = L.tail = p;
L.len = 0;
}
else
{
exit(ERROR);
}
}
void ClearList(LinkList &L)
{
//将线性链表L重置为空表,并释放原链表的结点空间
Link p, q;
if (L.head != L.tail)//不是空表
{
p = q = L.head->next;
L.head->next = NULL;
while (p != L.tail)
{
}
}
}
void DestroyList(LinkList &L)
{
//销毁线性表
ClearList(L);
FreeNode(L.head);
L.tail = NULL;
L.len = 0;
}
void InsFirst(LinkList &L, Link h, Link s)
{
//h指向L的一个结点,把h当做头结点,将s所指结点插入在第一个结点之前
//h = L.head->next;
s->next = h->next;
h->next = s;
if (h == L.tail)//h指向尾结点
{
L.tail = h->next;//修改尾指针
}
L.len++;
}
Status DelFirst(LinkList &L, Link h, Link &q)
{
//h指向L的一个结点,把h当做头结点,删除链表中的第一个结点,并以q返回
//若链表为空(h指向尾结点),q=NULL,返回FALSE
q = h->next;
if (q)//链表非空
{
h->next = q->next;
if (!h->next)//删除尾结点
{
L.tail = h;//修改尾指针
}
L.len--;
return OK;
}
else
{
return FALSE;//链表空
}
}
void Append(LinkList &L, Link s)
{
//将指针s(s->data为第一个数据元素)所指(彼此以指针相链,以NULL结尾)的一串结点链接在线性链表L的最后一个结点之后,并改变链表L的尾指针指向新的尾结点
int i = 1;
L.tail->next = s;
while (s->next)
{
s = s->next;
i++;
}
L.tail = s;
L.len += i;
}
Position PriorPos(LinkList L, Link p)
{
//已知p指向线性链表L中的一个结点,返回p所指结点的直接前驱的位置。若无前驱,则返回NULL
Link q;
q = L.head->next;
if (p == q)//无前驱
{
return NULL;
}
else
{
while (q->next != p)//q不是p的直接前驱
{
q = q->next;
}
return q;
}
}
Status Remove(LinkList &L, Link &q)
{
//删除线性链表L中的尾结点并以q返回,改变链表L的尾指针指向新的尾结点
Link p = L.head;
if (L.len == 0)//空表
{
q = NULL;
return FALSE;
}
while (p->next != NULL)
{
p = p->next;
}
q = L.tail;
p->next = NULL;
L.tail = p;
L.len--;
return OK;
}
void InsBefore(LinkList &L, Link &p, Link s)
{
//已知p指向线性链表L中的一个结点,将s所指结点插入在p所指结点之前,并修改指针p指向新插入的结点
Link q;
q = PriorPos(L, p);//q是p的前驱
if (!q)//p无前驱
{
q = L.head;
}
s->next = p;
q->next = s;
p = s;
L.len++;
}
void InsAfter(LinkList &L, Link &p, Link s)
{
//已知p指向线性链表L的中一个结点,将s所指结点插入在p所指结点之后,并修改指针p指向新插入的结点
if (p == L.tail)//修改尾指针
{
L.tail = s;
}
s->next = p->next;
p->next = s;
p = s;
L.len++;
}
void SetCurElem(Link p, ElemType e)
{
//已知p指向线性链表中的一个结点,用e更新p所指结点中数据元素的值
p->data = e;
}
ElemType GetCurElem(Link p)
{
//已知p指向线性链表中的一个结点,返回p所指结点中数据元素的值
return p->data;
}
Status ListEmpty(LinkList L)
{
//判断表空
if (L.len)
return FALSE;
else
return TRUE;
}
int ListLength(LinkList L)
{
//返回线性链表中元素个数
return L.len;
}
Position GetHead(LinkList L)
{
//返回线性链表L中头结点的位置
return L.head;
}
Position GetLast(LinkList L)
{
//返回线性链表L中最后一个结点的位置
return L.tail;
}
Position NextPos(Link p)
{
//已知p指向线性链表中的一个结点,返回p所指结点直接后继的位置,若无后继,则返回NULL
return p->next;
}
Status LocatePos(LinkList L, int i, Link &p)
{
//返回p指示线性链表L中第i个结点的位置,并返回OK,i值不合法时返回ERROR。i=0为头结点
int j;
if (i == 0)
{
p = L.head;
}
else if (i<0 || i>L.len)
{
return ERROR;
}
else
{
p = L.head->next;
for (j = 1; j < i; j++)
{
p = p->next;
}
return OK;
}
}
Position LocateElem(LinkList L, ElemType e, Status(*compare)(ElemType, ElemType))
{
//返回线性链表中第1个与e满足函数compare()判定关系的元素的位置
//若不存在这样的元素,则返回NULL
Link p = L.head;
do
{
p = p->next;
} while (p && !(compare)(p->data,e));//没找到表尾且没找到满足关系的元素
return p;
}
void ListTraverse(LinkList L, void(*visit)(ElemType))
{
//依次对L的每个数据元素调用函数visit()
Link p = L.head->next;
int j;
for (j = 1; j <= L.len; j++)
{
visit(p -> data);
p = p->next;
}
printf("\n");
}
void OrderInsert(LinkList &L, ElemType e, int(*comp)(ElemType, ElemType))
{
//已知L为有序线性链表,将元素e按非降序插入在L中。(用于一元多项式)
Link o, p, q;
q = L.head;
p = q->next;
while (p != NULL && comp(p->data, e) < 0)//p不说表尾且元素值小于e
{
q = p;
p = p->next;
}
o = (Link)malloc(sizeof(LNode));//生成结点
o->data = e;//赋值
q->next = o;//插入
o->next = p;
L.len++;
if (!p)//插在表尾
L.tail = o;
}
Status LocateElem(LinkList L, ElemType e, Position &q, int(*compare)(ElemType, ElemType))
{
//若升序链表L中存在与e满足判定函数compare()取值为0的元素,则q指示L中第一个值为e的结点的位置,并返回TRUE;
//否则q指示第一个与e满足判定函数compare()取值>0的元素的前驱的位置,并返回FALSE。(用于一元多项式)
Link p = L.head, pp;
do
{
pp = p;
p = p->next;
} while (p && (compare(p->data, e) < 0));//没到表尾且p->data<e
if (!p || compare(p->data, e))//到表尾或compare(p->data,e)>0
{
q = pp;
return FALSE;
}
else//找到
{
q = p;
return TRUE;
}
}
Status ListInsert_L(LinkList &L, int i, ElemType e)
{
//在带头结点的单链线性表的第i个元素之前插入e
Link h, s;
if (LocatePos(L, i - 1, h))
return ERROR;//i值不合法
MakeNode(s, e);//结点分配失败则退出
InsFirst(L, h, s);//对于从第i个结点开始的链表,第i-1个结点是它的头结点
return OK;
}
void MergeList_L(LinkList &La, LinkList &Lb, LinkList &Lc, int(*compare)(ElemType, ElemType))
{
//已知单链线性表La和Lb的元素按值非递减排列。
//归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列
Link ha, hb, pa, pb, q;
ElemType a, b;
InitList(Lc);//存储空间分配失败则退出
ha = GetHead(La);//ha,hb分别指向La和Lb的头结点
hb = GetHead(Lb);
pa = NextPos(ha);//pa和pb分别指向La和Lb的首元结点
pb = NextPos(hb);
while (pa && pb)//La和Lb非空
{
a = GetCurElem(pa);//a和b为两表中当前比较元素(第i个元素)
b = GetCurElem(pb);
if (compare(a, b) <= 0)//a<=b
{
DelFirst(La, ha, q);//移去La的首元结点并以q返回
q->next = NULL;//将q的next域赋值NULL,以便调用Append()
Append(Lc, q);//将q结点接在Lc的尾部
pa = NextPos(ha);//pa指向La新的首元结点
}
else//a>b
{
DelFirst(Lb, hb, q);//移去Lb的首元结点并以q返回
q->next = NULL;//将q的next域赋值NULL,以便调用Append()
Append(Lc, q);//将q结点接在Lc的尾部
pb = NextPos(hb);//pb指向Lb新的首元结点
}
}
if (pa)//La非空
{
Append(Lc, pa);//链接La中剩余结点
}
else//Lb非空
{
Append(Lc, pb);//链接Lb中剩余结点
}
free(ha);//销毁La和Lb
La.head = La.tail = NULL;
La.len = 0;
free(hb);
Lb.head = Lb.tail = NULL;
Lb.len = 0;
}
int diff(ElemType c1, ElemType c2)
{
return c1 - c2;
}
5.数据结构 线性表_增加指向头结点和最后一个结点的指针的结构的单链表
最新推荐文章于 2022-03-04 10:31:39 发布