//带头结点的线性链表
//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;
}
《数据结构复习》线性链表实现
最新推荐文章于 2024-07-20 09:21:06 发布