线性单链表的操作

Posted 影落明湖

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线性单链表的操作相关的知识,希望对你有一定的参考价值。

#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define INFEASIBLE  -1
#define OVERFLOW -2
/*
#define ElemType int
#define Status int
*/
typedef int ElemType;
typedef int Status;
/*
#define LNode LNode
#define LEN sizeof(LNode)
#define MLC (LNode *)malloc
#define MLCS (LNode *)malloc(sizeof(LNode))
*/
/*
//线性表的基本操作定义声明

Status InitList(SqList &L);
//操作结果:构造一个空的线性表L。 1

Status DestroyList(SqList &L);
//初始条件:线性表L已存在。
//操作结果:销毁线性表L。 2

Status ClearList(SqList &L);
//初始条件:线性表L已存在。
//操作结果:将L重置为空表。 3

bool ListEmpty(SqList L);
//初始条件:线性表L已存在。
//操作结果:若L为空表,则返回TRUE,否则返回FALSE。 4

int ListLength(SqList L);
//初始条件:线性表L已存在。
//操作结果:返回L中数据元素的个数。 5

Status GetElem(SqList L, int i, ElemType &e);
//初始条件:线性表L已存在,1<=i<=ListLength(L)。
//操作结果:用e返回L中第i个数据元素的值。 6

int LocateElem(SqList L, int e, bool(*equal)(ElemType, ElemType));
//初始条件:线性表L已存在,compare()是数据元素判定函数。
//返回L中第一个与e满足关系compare()的数据元素的位序。若这样的数据元素不存在,则返回值为0. 7

Status PriorElem(SqList L, ElemType cur_e, ElemType &pre_e);
//初始条件:线性表L已存在。
//操作结果:若cur_e是L中的数据元素,且不是第一个,则用pre_e返回它的前驱,否则操作失败,pre_e无定义。 8

Status NextElem(SqList L, ElemType cur_e, ElemType &next_e);
//初始条件:线性表L已存在。
//操作结果:若cur_e是L中的数据元素,且不是最后一个,则用next_e返回它的后继,否则操作失败,next_e无定义。9

Status ListInsert(SqList &L, int i, ElemType e);
//初始条件:线性表L已存在,1<=i<=ListLength(L)+1.
//操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1. 10

Status ListDelete(SqList &L, int i, ElemType &e);
//初始条件:线性表L已存在且非空,1<=i<=ListLength(L).
//操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1. 11

Status ListTraverse(SqList L, bool(*visit)(ElemType));
//初始条件:线性表L已存在
//操作结果:依次对L的每个元素调用函数visit().一旦visit()失败,则操作失败。 12
*/
/*
//线性表的基本操作定义声明
InitList(&L) //初始化线性表L  1
DestroyList(&L) //销毁线性表L  2
ClearList(&L) //清空线性表L  3
ListEmpty(L) //判断线性表是否为空 4
ListLength(L) //求线性表L的长度 5
GetElem(L,i,&e) //取线性表L的第i个元素 6
LocateElem(L,e,compare()) //定位检索线性表L中元素e 7
PriorElem(L,cur_e,&prio_e) //返回线性表L中元素e的直接前驱元素 8
NextElem(L,cur_e,&next_e) //返回线性表L中元素e的直接后继元素 9
ListInsert(&L,i,e) //在线性表L的第i个元素之前插入元素e,返回Bool 10
ListDelete(&L,i,e) //删除线性表L的第i个元素,被删除元素e的值,返回Bool 11
ListTraverse(L,visit()) //遍历线性表:依次对L的每个元素调用visit() 12
*/
/*进阶算法
//reverseList(&L1) //逆置 单链表
//mergeList(&L1,L2) //合并 两个线性表L 15
//visit(e) //  一般是指树型链表结构中对某个节点内容进行访问的函数, 13
//compare(e1,e2) //比较两个元素的大小,返回Bool 14
//compareList(L1,L2) //比较两个线性表L的大小,返回Bool 14
//mergeList(&L1,L2) //合并两个线性表L 15
//Status AppendBefore(List &L, ElemType e) //头插元素
//Status AppendAfter(List &L, ElemType e) //尾插元素
*/
/*---------------线性单链表----------------
单链表 初始化 创建 头插法 尾插法 插入 删除 查找 合并 长度
*/
typedef struct LNode { //封装 结构体 链表的结点==数据元素Elem,结点的指针==链表==数据对象Obj
	ElemType data; //数据Domain ,数据项item
	struct LNode *next; //指针,引用Reference	
}LNode, *LinkList, *LNodePtr;//类型重定义struct LNode为LNode,类型重定义 LNode的*指针 为LinkList
Status InitList(LinkList &L) { //初始化线性链表 产生一个头结点。单链表指针在外面传进来	
	//head
	//?→NULL?
	//表头指针 从函数外面传进来
	L = (LNode *)malloc(sizeof(LNode));
	if (!L) { /* 存储分配失败 */
		exit(OVERFLOW);
	}
	L->next = Null;//结尾指向空
	return TRUE;
}
Status CreateList_Link_Tail_Guan(LinkList &L, int n) {
	//单向链表的创建过程
	//ptemp辅助指针
	// ↓=head
	// ?→NULL
	//ptemp
	//   ↓.next +1
	// ??→NULL
	//ptemp
	//    ↓.next +1
	// ???→NULL
	/*
	从上面的示意图可以看出,我们需要一个辅助指针一直指向最后一个结点,
	这个辅助结点就是为了让每次添加的结点都放置在最后一个位置。
	*/
	//表头指针 从函数外面传进来
	LinkList head = &L, ptemp, pnew;
	ptemp = head;//ptemp辅助指针 必须保证指向尾部,pointer points at head, CORE
	for (int i = n; i >= 1; --i) { // crete n num LNode
		pnew = (LinkList)malloc(sizeof(LNode));//生成新结点 SeCORE 开辟新节点
		scanf(%i, &pnew->data);//scanf data to dataArea,  SeCORE 输入数据
		pnew->next = NULL;//the pnew must be tail LNode.  CORE	
		ptemp->next = pnew;//对象obj(*ptemp).next 连接link to pnew, CORE
		ptemp = pnew;//ptemp++  CORE
	}
}
void CreateList_Link_Head_Yan(LinkList &L, int n) {
	//头插法 生成单链表 完整表
	//逆位序输入n个元素的值,建立带表头结点的单链线性表L
	L = (LinkList)malloc(sizeof(LNode));
	L->next = NULL;//L->next表示头结点的指针,先建立一个带头结点的单链表
	for (i = n; i > 0; --i) {
		p = (LinkList)malloc(sizeof(LNode));
		scanf(&p->data);//输入元素值
		p->next = L->next;//挪动 头指针的后继
		L->next = p;//挪动 头指针的后继
	}
}
Status Insert_Link(LinkList L, int i, ElemType e) {
	LinkList pre, ins; //pre为前驱结点,ins为新结点
	pre = L;
	int l = 1;
	while (p && j < i - 1) { //寻找第i个结点,指针下移,j最后停在i
		p = p->next; ++j;
	}
	if (!p || j > i) return FALSE;//第i个元素不存在
	ins = (LinkList)malloc(LEN);
	ins->data = e;
	ins->next = pre->next;
	pre->next = ins;
	return TRUE;
}
Status ListInsert(LinkList &L, int i, ElemType e) { //在带head的单链表L中第i个位置之前插入元素e	
	//前插操作需要查找第i个位置的结点的直接前驱。
	p = L; j = 0;//p为指针,被插入的previous LNode
	while (p && j < i - 1) { p = p->next; ++j; }//寻找第i-1个结点,指针下移,j最后停在i-2
	if (!p || j > i) return FALSE;

	s = (LinkList)malloc(sizeof(LNode));//生成新节点,开辟内存空间 返回指针s,insert
	s->data = e;//s->data域的赋值 assignment

	s->next = p->next;//指针操作 ,=右往左,指针 指向,core
	p->next = s;//core
	return TRUE;
}
Status ListInsert_Post(LinkList &L, int i, ElemType e) { //在带head的单链表L中第i个位置之后插入元素e	
	//后插操作需要查找第i个位置的结点的引用。设p为第i个位置的结点的引用
	p = L; j = 0;//p为指针,被插入的previous LNode
	while (p && j < i) { p = p->next; ++j; }//寻找第i-1个结点,指针下移,j最后停在i-2
	if (!p || j > i) return FALSE;

	s = (LinkList)malloc(sizeof(LNode));//生成新节点,开辟内存空间 返回指针s,insert
	s->data = e;//s->data域的赋值 assignment

	s->next = p->next;//指针操作 ,=右往左,指针 指向,core
	p->next = s;//core
	return TRUE;
}
Status ListDelete_Link_Yan(LinkList &L, int i, ElemType &e) { //在带head的单链表L中第i个位置 删除元素e		
	p = L; j = 0;//p为指针,被插入的previous LNode
	while (p && j < i - 1) { p = p->next; ++j; }//寻找第i个结点,下标最后是i-1,指针下移,j最后停在i
	if (p->next || j > i - 1) return FALSE;//删除位置不合理

	q = p->next; //q是被删除的节点	
	p->next = q->next;//P的next,指向q->next

	e = q->data; //取出 值为e
	free(q);//返回值,释放空间
}
LNode *LocateLinkElem(LinkList L, ElemType e) {
	//在L中找到第一个值和e相同的结点,返回其地址,若不存在,返回空值NULL。
	if (!L) return NULL;
	p = L;
	while (p&&p->data != e) { p = p->next };//if(!p) p=null;
	return p;//时间复杂度O(n)
}

int ListLength_Link(struct LNode *head) {//求线性单链表长度
	struct LNode *p = head->next;//LNode1
	int len = 0;
	while (p) {
		len++;
		p = p->next;
	}
	head->data = len; //存储长度到头结点的数据域head->data
	return len;
}
Status GetElem_Link_Yan_OutBool(LinkList L, int i, ElemType &e) {
	//取出元素,i是序号,e为值
	//L为带头结点的单链表的头节点
	//L-next为 带头结点的单链表的 头指针 指向第一个结点LNode1
	//当第i个元素存在时,将值返回给e,返回TRUE, 否则FALSE
	LinkList p = L->next;//初始化,p指向第一个结点,
	int j = 1;//j为计数器
	while (p && j < i) { //p指针非空,j计数器<i,所以循环的终点是i
		p = p->next; ++j;//指针后移一个,计数器+1一个
	}
	if (!p || j > i) return FALSE;//第i个元素不存在
	e = p->data;//取出第i个元素,值为e
	return TRUE;
}//GetElem_Link_Yan
ElemType GetElem_Link_OutData_Guan(LinkList L, int i) {
	//取出元素,i是序号,e为值
	//L为带头结点的单链表的头节点
	//L-next为 带头结点的单链表的 头指针 指向第一个结点LNode1
	//当第i个元素存在时,将值返回给e,返回TRUE, 否则FALSE
	LinkList p = L->next;//初始化,p指向第一个结点,
	int j = 1;//j为计数器
	while (p && j < i) { //p指针非空,j计数器<i,所以循环的终点是i
		p = p->next; ++j;//指针后移一个,计数器+1一个
	}
	if (!p || j > i) return FALSE;//第i个元素不存在
	ElemType e = p->data;//取出第i个元素,值为e
	return e;
}

void ReLinkCirleListBefore(LNode *s, LNode *q) {
	//Link Cirle, s linke before LNode q
	//从LNode *s开始,找到LNode q之前的结点 连接到s,组成一个新的循环链表
	P = s;
	while (p->next != q) p = ->next;
	p->next = s;
}//BackBefore
void ReLinkCirleListBeforeThenReLinkTheReminder(LNode *pa, LNode *pb) {
	//从LNode *pa开始,找到LNode pb之前的结点 连接到pa,组成一个新的循环链表,然后,从pb结点开——连接到pa之前的结点,组成一个新的循环链表
	//2次
	//Link Cirle,twice,
	//pa,pb finger LinkStack‘s two node. a link before b, b linke befor a.
	BackBefore(pa, pb);
	BackBefore(pb, pa);
}//BackBeforeAfterAgain

Status LinkList_DelBetween(LinkList &L, ElemType mink, ElemType maxk) {
	//删除大于mink小于maxk的所有元素,L是带头结点的单链表
	P = L; //temp Ptr P finger L‘s head, then P finger mink‘s 前驱。
	while (P->next != NULL && P->next->data <= mink) //then P finger mink‘s 前驱。
		P = P->next;//find the node before mink //找出第last个大于mink的元素
	if (P->next = NULL) return FALSE; //mean mink‘s 前驱 not 存在 ,( !P->next )
	Q = P->next; //temp Ptr Q finger mink
	while (!Q && (Q->data < maxk)) { //DestroyList()
		P->next = Q->next; //?
		free(Q); //?
		Q = P->next; //? ♂
	}
}//LinkList_BetweenDel
Status AppendHead(LinkList &L, ElemType e) { //头插元素
	LNodePtr s = (LNode *)malloc(sizeof(LNode)); //开辟新节点
	s->data = e; //新节点 数据赋值

	s->next = L->next; //? ? //头插元素 核心//? ? //? ♂//head 不存数据
	L->next = s; //? ♂
}
Status AppendAfter(LinkList &L, ElemType e) { //尾插元素
	LNodePtr s = (LNode *)malloc(sizeof(LNode));//开辟新节点
	s->data = e; //新节点 数据赋值

	LinkList p;//tempPtr
	p = L;
	while (p->next != NULL) { //找end的precursor前驱
		P = P->next; //找end的precursor前驱,Ptr++ move 
	}
	//尾插元素 核心
	//? ? //? ♂
	P->next = s; //? ?
	s->next = NULL; //? ♂
}
void MergeLinkList_ToOld_ASC_Tan_4StarHard(LinkList &La, LinkList &Lb) {
	//已知La和Lb升序排列
	//合并得到新的单链表Lc,Lc的元素也按值非递减排列
	LinkList pa, pb, p, q;
	pa = La->next;
	pb = Lb->next;
	q = La;//存放临时指针,q就是pa的前驱元素,q必须始终作为pa的前驱元素
	t = Lb;
	while (pa && pb) {
		if (pa->data <= pb->data) {//如果小于=,pc指针指向pa
			q = pa;//q下移 
			pa = pa->next;//pa下移
		} else {
			//如果 且 只有 在    pa->data > pb->data,则将pb插入到pa的前面
			//转化 判断条件 如果 pb->data > pa->data ,则将pb插入到pa的前面
			t = pb;// t 下移
			pb = pb->next;//pb下移
			t->next = pa;//pb插入到pa的前面
			q->next = t;
			q = t;//q必须始终作为pa的前驱元素,因此t赋值给q
		}//2个结合起来就是小者排前面,这个代码写的真差,不是人类看的,因为C在A和B只见跳来跳去,临时pc变量拆成2个就容易理解了
	}
	if (pb) { //pb存在
		q->next = pb; //插入所有剩余的pb
	}
}//MergeList_Link_Yan
Status MergeLinkList_ToOld_ASC_3ptr_Tan_4StarHard(LinkList &A, &B, &C) {
	/*
	//合并得到新的单链表Lc,降序
	//已知La和Lb升序排列
	//合并得到新的单链表Lc,Lc的元素 按值
	//非递增排列LinkList p, q, pc;
	//C必须 使用A,B原来的结点空间
	*/
	LinkList p, q; //p & q is TempPtr。必须前提,head不存数据 //neccesory,head no repos data
	LinkList s; //s is TempPtr. finger New Node of C.//s作为c的TempPtr	
	p = A->next; q = B->next; //p q Node1。//p & q 必须始终作为 A & B 的FirstNode元素
	C = B; C->next = NULL; free(A); //InitList(Lc),C use B Repos,C is head
	//MergeList_ToOld_DSC降序合并,思路,比较大小后,把数值小的节点链接到 单链表C上面
	while (p && q) { //同时存在
		if (p->data <= q->data) { //curent min is p
			s = p; p = p->next; //s finger curent min //p++
		} else { //(p->data > q->data) //curent min is q
			s = q; q = q->next; //s finger curent min //q++
		}
		s->next = C->next; //s is current node,头插
		C->next = s; //s node Head AppendBefore() ListC. 头插
	}
	if (!p) p = q; //p is null
	while (p) { // q is null ,q end. p append C
		s = p; // s finger cur
		p = p->next; //p++ move
		s - next = C->next; //s.next finger C.next<==> C node1,头插
		C->next = s; //头插
	}
	/*
	//---------------
	while (p && q) { //p,q 存在
		if (p->data <= q->data) { //如果小于=,pc指针指向p
			AppendBefore(pc, p->data);
			v = p;//v下移
			p = p->next;//p下移
		}
		else { //如果>
			   //如果 且 只有 在    p->data > q->data,则将q插入到p的前面
			   //转化 判断条件 如果 q->data > p->data ,则将q插入到p的前面
			w = q;// w 下移
			q = q->next;//q下移
			w->next = p;//q插入到p的前面
			v->next = w;
			v = w;//v必须始终作为p的前驱元素,因此w赋值给v
		}//2个结合起来就是小者排前面,这个代码写的真差,不是人类看的,因为C在A和B只见跳来跳去,临时pc变量拆成2个就容易理解了
	}//while
	if (q) { //q存在
		v->next = q; //插入所有剩余的q
	}
	//-------------
	*/
}//MergeLinkList_ToOld_DSC_3ptr_Tan
Status MergeLinkList_ToNew_ASC_6Ptr_Guan_3StarHard(LinkList La, LinkList Lb, LinkList &Lc) { //合并得到新的单链表Lc,降序
	//已知La和Lb升序排列
	//合并得到新的单链表Lc,Lc的元素也按值非递减排列
	LinkList pa, pb, pc;
	LinkList p, t, u;

	pa = La->next;
	pb = Lb->next;
	pc = Lc->next;

	q = La; //存放临时指针,q就是pa的前驱元素,q必须始终作为pa的前驱元素
	t = Lb; //存放临时指针,t就是pb的前驱元素,t必须始终作为pb的前驱元素
	u = Lc; //存放临时指针,u就是pc的前驱元素,u必须始终作为pc的前驱元素

	while (pa && pb) { //pa,pb 存在
		if (pa->data <= pb->data) { //如果小于=,pc指针指向pa
			AppendBefore(pc, pa->data);//apd c
			q = pa;//q下移 
			pa = pa->next;//pa下移
		} else { //如果 pb->data < pa->data
			//如果 且 只有 在    pa->data > pb->data,则将pb插入到pa的前面
			//转化 判断条件 如果 pb->data > pa->data ,则将pb插入到pa的前面
			AppendBefore(pc, pb->data);//apd c
			t = pb;// t 下移
			pb = pb->next;//pb下移
			/*
			//t->next = pa;//pb插入到pa的前面
			//q->next = t;
			//q = t;//q必须始终作为pa的前驱元素,因此t赋值给q
			*/
		}//2个结合起来就是小者排前面,这个代码写的真差,不是人类看的,因为C在A和B只见跳来跳去,临时pc变量拆成2个就容易理解了
	}//while
	if (pa) { //pb存在
		u->next = pa; //插入所有剩余的pb
	}
	if (pb) { //pb存在
		u->next = pb; //插入所有剩余的pb
	}
}//MergeList_To_DSC_List

Status MergeLinkList_ToNew_Union_ASC_6Ptr_Guan_3StarHard(LinkList La, LinkList Lb, LinkList &Lc) { //合并得到新的单链表Lc,求并集																				 //合并得到新的单链表Lc,Lc的元素也按值非递减排列
	LinkList pa, pb, pc;
	LinkList p, t, u;
	pa = La->next;
	pb = Lb->next;
	pc = Lc->next;
	q = La; //存放临时指针,q就是pa的前驱元素,q必须始终作为pa的前驱元素
	t = Lb; //存放临时指针,t就是pb的前驱元素,t必须始终作为pb的前驱元素
	u = Lc; //存放临时指针,u就是pc的前驱元素,u必须始终作为pc的前驱元素
	ElemType e;// temp data
	while (pa && pb) { //pa,pb 存在
		if (pa->data <= pb->data) { //如果小于=,pc指针指向pa
			e = pa->data;
			if (!LocateLinkElem(Lc, e)) AppendAfter(pc, pa->data);//apd c
			q = pa;//q下移 
			pa = pa->next;//pa下移
		} else {
			/*
			//如果 pb->data < pa->data
			   //如果 且 只有 在    pa->data > pb->data,则将pb插入到pa的前面
			   //转化 判断条件 如果 pb->data > pa->data ,则将pb插入到pa的前面
			*/
			e = pa->data;
			if (!LocateLinkElem(Lc, e)) AppendAfter(pc, pb->data);//apd c
			t = pb;// t 下移
			pb = pb->next;
			/*
			pb下移
			//t->next = pa;//pb插入到pa的前面
			//q->next = t;
			//q = t;//q必须始终作为pa的前驱元素,因此t赋值给q
			*/
		}//2个结合起来就是小者排前面,这个代码写的真差,不是人类看的,因为C在A和B只见跳来跳去,临时pc变量拆成2个就容易理解了
	}//while
	if (pa) { //pb存在
		u->next = pa; //插入所有剩余的pb
	}
	if (pb) { //pb存在
		u->next = pb; //插入所有剩余的pb
	}
}//MergeLinkList_ToNew_Union_ASC_6Ptr_Guan_3StarHard
Status MergeLinkList_ToNew_Intersection_ASC_6Ptr_Guan_3StarHard(LinkList La, LinkList Lb, LinkList &Lc) { //合并得到新的单链表Lc,求交集																				 //合并得到新的单链表Lc,Lc的元素也按值非递减排列
	LinkList pa, pb, pc;
	LinkList p, t, u;
	pa = La->next;
	pb = Lb->next;
	pc = Lc->next;
	q = La; //存放临时指针,q就是pa的前驱元素,q必须始终作为pa的前驱元素
	t = Lb; //存放临时指针,t就是pb的前驱元素,t必须始终作为pb的前驱元素
	u = Lc; //存放临时指针,u就是pc的前驱元素,u必须始终作为pc的前驱元素
	ElemType e;// temp data
	while (pa && pb) { //pa,pb 存在
		if (pa->data <= pb->data) { //如果小于=,pc指针指向pa
			e = pa->data;
			if (LocateLinkElem(La, e) && LocateLinkElem(Lb, e)) AppendAfter(pc, pa->data);//apd c
			q = pa;//q下移 
			pa = pa->next;//pa下移
		} else {
			/*
			//如果 pb->data < pa->data
			//如果 且 只有 在    pa->data > pb->data,则将pb插入到pa的前面
			//转化 判断条件 如果 pb->data > pa->data ,则将pb插入到pa的前面
			*/
			e = pa->data;
			if (LocateLinkElem(La, e) && LocateLinkElem(Lb, e)) AppendAfter(pc, pb->data);//apd c
			t = pb;// t 下移
			pb = pb->next;
			/*
			pb下移
			//t->next = pa;//pb插入到pa的前面
			//q->next = t;
			//q = t;//q必须始终作为pa的前驱元素,因此t赋值给q
			*/
		}//2个结合起来就是小者排前面,这个代码写的真差,不是人类看的,因为C在A和B只见跳来跳去,临时pc变量拆成2个就容易理解了
	}//while
	if (pa) { //pb存在
		u->next = pa; //插入所有剩余的pb
	}
	if (pb) { //pb存在
		u->next = pb; //插入所有剩余的pb
	}
}//MergeLinkList_ToNew_Union_ASC_6Ptr_Guan_3StarHard

Status LL_Detete_In_A_By_B_Inter_C(SqList &A, SqList B, SqList C) {
	//删除A中满足条件的元素:同时在B/C中出现的元素
	LNodePtr p = A; //temp Ptr
	LNodePtr q; //temp Ptr for free() node,临时指针for删除结点
	ElemType e; //temp data
	while (p->next != NULL) {
		e = p->next->data; //赋值
		if ((LocateElem(B, e) != 0) && (LocateElem(C, e) != 0)) {
			q = p->next; //q finger p head after node which node1
			p->next = q->next; //p+2 move
			ListDelete(q); //dispose(q),ListDelete(q);
		} else p = p->next;//p++ move
	}//while

	/* Sqlist only
	for (size_t i = 0; i < length; i++) {
		e = A.elem[i];
		if ((LocateElem(B, e)) && (LocateElem(C, e))) {
			ListDelete(A, i + 1);
		}//if
	}//for
	*/
}//Sq_Detete_In_A_By_B_Inter_C

Status ReverseLink_InOld(LinkList &h) {
	//就地逆置
	//假设在头结点,H为指向头结点的指针
	//只需将头结点后结点依次加入新链,
	//加入总是放在新链的首元素位置上
	LNodePtr p, q;
	p = h->next;
	h->next = NULL; //h finger head
	while (t != NULL) {
		q = p;//q前驱
		p = p->next;//p后继	 
		q->next = h->next;//头插法
		h->next = q;
	}
	return TRUE;
}//ReverseLink_InOld

  

以上是关于线性单链表的操作的主要内容,如果未能解决你的问题,请参考以下文章

数据结构:线性表顺序表以及单链表详解

线性单链表的操作

数据结构之单链表

顺序存储和链式存储线性表的基本操作(王道)

[Data Structure]线性表Linear List2

线性表的链式存储结构 ( 链表 )