单链表(带头结点)的基础操作(c++)

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// 单链表存储结构 
typedef struct LNode{
	int data;
	struct LNode *next;
}LNode,*LinkList; 

// 带头结点的单链表初始化 
bool InitList(LinkList &L){    
	L=(LNode*)malloc(sizeof(LNode)); //创建头结点 
	L->next = NULL; //头结点的指针,即头结点之后暂时没有元素的结点 
	return true;
}

//判空操作 
int IsEmpty(LinkList L) {
    return L->next == NULL;  // 头结点的next指向NULL时,表示链表为空
}

//求表长
int GetLength(LinkList L) {
    int length = 0;
    LNode *p = L->next;  // 从头结点的下一个结点开始
    while (p != NULL) {
        length++;
        p = p->next;
    }
    return length;
} 

//按位序查找
LNode* GetElem(LinkList L, int i) {
    int j = 1;
    LNode *p = L->next;
    while (p != NULL && j < i) {
        p = p->next;
        j++;
    }
    return p;  // 若找到返回指针,若i超出范围则返回NULL
}

//按值查找
LNode* LocateElem(LinkList L, int value) {
    LNode *p = L->next;
    while (p != NULL) {
        if (p->data == value)
            return p;  // 返回指向该元素的指针
        p = p->next;
    }
    return NULL;  // 没有找到
}

//指定结点的后插操作(在p结点之后插入元素e) 
int InsertNextNode(LNode *p, int e) {
    if (p == NULL) return 0;

    LNode *newNode = (LNode*)malloc(sizeof(LNode));
    if (newNode == NULL) return 0;

    newNode->data = e;
    newNode->next = p->next;
    p->next = newNode;

    return 1;  // 插入成功
}
 
//指定结点的前插操作(在p结点之前插入元素e)——值交换+后插技巧 
int InsertPriorNode(LNode *p, int e) {
    if (p == NULL) return 0;

    LNode *newNode = (LNode*)malloc(sizeof(LNode));
    if (newNode == NULL) return 0;

    // 把原结点的数据复制到新结点
    newNode->data = p->data;
    newNode->next = p->next;

    // 把新数据放入p,再将p指向新结点
    p->data = e;
    p->next = newNode;

    return 1;
}

//指定结点的前插操作(在p结点之前插入元素e)——遍历找到前驱结点
int InsertBeforeNode(LinkList &L, LNode *p, int e) {
    if (L == NULL || p == NULL) return 0;
    LNode *pre = L;  // 从头结点开始找前驱
    while (pre->next != NULL && pre->next != p) {
        pre = pre->next;
    }
    if (pre->next != p) return 0;  // p不是链表中的结点

    // 找到了前驱,执行后插
    return InsertNextNode(pre, e);
}

//按位插入操作 
int ListInsert(LinkList &L, int i, int e) {
    if (i < 1) return 0;  // 位置不合法
    LNode *p = L;  //指针p当前扫描到的结点 
    int j = 0;  //记录当前节点的位序,头结点是第0个结点 
    // 找到第i-1个结点
    while (p != NULL && j < i - 1) {
        p = p->next;
        j++;
    }
    
    InsertNextNode(p, e); 
    /* 
    if (p == NULL) return 0;  // 第i-1个结点不存在,插入失败

    // 创建新结点
    LNode *newNode = (LNode*)malloc(sizeof(LNode));
    if (newNode == NULL) return 0;  // 内存分配失败

    newNode->data = e;  // 设置数据
    newNode->next = p->next;  // 新结点指向原来的下一个结点
    p->next = newNode;  // 第i-1个结点的next指向新结点
	*/
    return 1;  // 插入成功
}

//按位序删除结点(删除第 i 位元素,返回被删除元素的值)
int ListDelete(LinkList &L, int i, int &e) {
    if (i < 1) return 0;  // 位置不合法
    LNode *p = L;   
    int j = 0;
    // 找到第i-1个结点
    while (p != NULL && j < i - 1) {
        p = p->next;
        j++;
    }
    if (p == NULL || p->next == NULL) return 0;  // 第i-1个结点不存在,删除失败

    LNode *q = p->next;  // 被删除的结点
    e = q->data;        // 保存被删除的值
    p->next = q->next;    // 将第i-1个结点的next指向第i+1个结点
    free(q);  // 释放被删除结点的内存

    return 1;  // 删除成功
}

//删除指定结点p(如果p是最后一个结点,只能从表头开始依次寻找p的前驱) 
bool  DeleteNode(LNode *p){
	if(p==NULL)
		return false;
	LNode *q = p->next;
	p->data=p->next->data;
	p->next=q->next;
	free(q);
	return true;
} 

void PrintList(LinkList L) {
    LNode *p = L->next;
    printf("链表元素:");
    while (p != NULL) {
        printf("%d ", p->data);
        p = p->next;
    }
    printf("\n");
}

//销毁
void DestroyList(LinkList &L) {
    LNode *p = (L)->next;
    while (p != NULL) {
        LNode *temp = p;
        p = p->next;
        free(temp);
    }
    free(L);  // 释放头结点
    L = NULL;  // 将链表指针置为NULL
}

//使用尾插法建立单链表(从空表建立) 
LinkList List_TailInsert(LinkList &L){
	int x;
	L=(LNode*)malloc(sizeof(LNode));
	LNode *s,*r=L;
	scanf("%d",&x);
	while(x!=9999){
		s=(LNode *)malloc(sizeof(LNode));
		s->data=x;
		r->next=s;
		r=s;
		scanf("%d",&x);
	}
	r->next=NULL;
	return L;
} 

//使用头插法建立单链表(从空表建立) 
LinkList List_HeadInsert(LinkList &L){
	int x;
	L=(LNode*)malloc(sizeof(LNode));
	LNode *s;
	L->next=NULL;
	scanf("%d",&x);
	while(x!=9999){
		s=(LNode *)malloc(sizeof(LNode));
		s->data=x;
		s->next=L->next;
		L->next=s;
		scanf("%d",&x);
	}
	return L;
} 

int main() {
    LinkList L;
    InitList(L);

    // 插入元素
    ListInsert(L, 1, 10);
    ListInsert(L, 2, 20);
    ListInsert(L, 3, 30);
    PrintList(L);

    // 获取链表长度
    printf("链表长度: %d\n", GetLength(L));

    // 按值查找
    LNode *node = LocateElem(L, 20);
    if (node != NULL)
        printf("找到值20,数据为: %d\n", node->data);
    else
        printf("未找到值20\n");

    // 按位查找
    node = GetElem(L, 2);
    if (node != NULL)
        printf("第2个元素是: %d\n", node->data);
    else
        printf("第2个元素不存在\n");

    // 删除元素
    int deleted;
    if (ListDelete(L, 2, deleted))
        printf("删除元素: %d\n", deleted);
    PrintList(L);
    
	List_TailInsert(L);
    PrintList(L);

	// 销毁链表
    DestroyList(L);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值