《数据结构复习》线性链表实现

//带头结点的线性链表
//ch1_1
#include<stdio.h>
#include<stdlib.h>
#define error -1
#define false -1
#define ok 1
typedef int status;
typedef int Elemtype;

typedef struct LNode {//结点
	int data;
	struct LNode* next;
}*Link,*Position;

typedef struct {//链表
	Link head, tail;
	int len;
}LinkList;

//产生一个结点
Position makenode1(int e) {
	Link p = (Link)malloc(sizeof(struct LNode));//分配结点
	p->data = e;			
	p->next = NULL;			//指针域为空
	return p;
}
status makenode2(Link* p, int e) {
	(*p)=(Link)malloc(sizeof(struct LNode));//有疑问
	if (!(*p)) return error;
	(*p)->data = e;
	(*p)->next = NULL;
	return ok;
}
//释放p结点
void freenode(Link* p) {
	free(*p);
}
//空的线性表
status initlist(LinkList* L) {
	L->head = makenode1(0);
	L->head->next = NULL;
	L->tail = L->head;
	L->len = 0;
	return ok;
}
//h,指向头结点,插入到第一个结点之前
status insfirst(LinkList* h, Link s) {
	s->next = h->head->next;	//插入到头结点之后
	if (!h->head->next)
		h->tail = s;			//原链表没有结点,尾结点也指向s
	h->head->next = s;
	h->len++;
	return ok;
}
//h头结点,删除链表第一个元素
Position DelFirst(LinkList* L) {
	Link p = L->head->next;
	if (L->len == 0) {		//链表中没有元素
		printf("链表为空,返回头结点");
		p = L->head;
		return p;
	}
	if (!L->head->next->next) {//链表只有一个结点
     //if (L->len==1)
		L->head->next = NULL;
		L->tail = L->head;
		L->len--;
		return p;
	}
	L->head->next = L->head->next->next;  //头结点后继向下移动
	L->len--;
	return p;
}
//将s的一串结点连接在线性表L的最后一个结点
status append(LinkList* L, Link s) {
	Link p = s;
	while (p) {
		L->tail->next= p;	//连接在后面
		L->tail = p;		//移动尾指针
		L->len++;
		p = p->next;
	}
	return ok;
}
//打印链表
void printList(Link h) {
	while (h) {
		printf("%d ", h->data);
		h = h->next;
	}
	printf("\n");
}
/*删除尾结点并返回
Position remove(LinkList* L) {
	Link p, q;
	p = (*L).head;
	q = (*L).tail;
	if ((*L).len == 0) {
		printf("空链表");
		return p;
	}
	if ((*L).len == 1) {		//链表只有一个结点
		(*L).head->next = NULL;
		(*L).tail = (*L).head;
		(*L).len--;
		p = p->next;
		return p;
	}
	while (p->next != q) {	//找到尾结点前面一个结点
		p = p->next;
	}
	L->tail = p;
	L->tail->next = NULL;
	L->len--;
	return p;
}*/
//得到第i个结点
Position locatepos(LinkList* L, int i) {
	Link p = L->head;
	if (i<=0||i > L->len) {
		printf("第%d个结点不存在",i);
		return p;
	}
	for (int j = 0; j < i; j++) {	//找到前一个结点
		p = p->next;
	}
	return p;
}
//将s插入到p之前
status insbefore(LinkList* L, Link* p, Link s) {
	Link q = L->head;
	while (q->next != (*p)) {	//找到前一个结点
		q = q->next;
	}
	s->next = (*p);
	q->next = s;
	L->len++;
	return ok;
}
//将s插入到p之后
status insafter(LinkList* L, Link* p, Link s) {
	Link q = (*p)->next;
	(*p)->next = s;
	s->next = q;
	L->len++;
	if (L->tail == (*p)) {
		L->tail = s;
	}
	return 0;
}
//p指向链表中的一个结点,用e更新p所指结点中数据元素的值
status setcurelem(Link* p, int e) {
	(*p)->data = e;
	return ok;
}
//返回p指向的结点的值
int GetCurElem(Link p) {
	return p->data;
}
//若链表为空,返回TRUE,否则返回FALSE
status listEmpty(LinkList L) {
	if (L.head->next==NULL) {
		return false;
	}
	return ok;
}
//返回链表中元素的个数
int listlength(LinkList L) {
	return L.len;
}
//返回p所指结点的前驱
Position priorpos(LinkList L, Link p) {
	Link q = L.head;
	if (L.head->next == p) {
		printf("无前驱");
		return q;
	}
	while (q->next != p) {
		q = q->next;
	}
	return q;
}
//返回p所指结点的后继
Position nextpos(LinkList L, Link p) {
	Link q = L.head;
	if (L.tail == p) {
		printf("无后继");
		return q;
	}
	q = p->next;
	return q;
}

int main() {
	LinkList a, b;
	Link p, q;
	initlist(&a);//初始化链表
	initlist(&b);
	for (int i = 0; i < 10; i++) {//构造结点,插入a链表
		p = makenode1(i);
		insfirst(&a, p);
	}
	for (int i = 11; i < 20; i++) {//构造结点,插入b链表
		p = makenode1(i);
		insfirst(&b, p);
	}

	printList(a.head);//打印链表
	printList(b.head);
	append(&a, b.head->next);//连接a,b链表
	printList(a.head);
	q=locatepos(&a, 7);//取出第七个结点
	printf("第7个元素:%d",q->data);
	printf("\n");
	Link s = makenode1(100);
	insbefore(&a, &q, s);	//在q之前插入100
	printList(a.head);
	Link m = makenode1(111);
	insafter(&a, &q, m);	//在q之后插入111
	printList(a.head);
	setcurelem(&q, 333);	//改变q结点数值
	printList(a.head);
	return 0;
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值