无头结点单链表的特点、增删改查及逆置

一.特点:

(1)有一个head指针变量,存放头结点的地址,称为头指针。

(2)头结点的指针域head—>,存放第一个有效节点的地址。

(3)每个节点都包含一个数据域和指针域,数据域存放此节点的数据,指针域存放下一个节点的地址。最后一个节点的指针域为NULL,防止乱指。

(4)链表中各节点的顺序关系由指针域next确定,随机分配空间,不需要占用连续的内存空间。

二. 增删改查

首先建立一个结构体

typedef struct node   
{
	int a;
	char b;
	struct node* next;  //定义一个指向本结构体类型的指针类型
}Node,*LinkList;        //Node是结构体类型,是struct node的别名,
                          LinkList是结构体指针类型,LinkList head相当于 Node* head,也相当于struct node* head

1. 增

(1)尾插法

void Creat_Rear(LinkList head)
{
	LinkList head1 = NULL, p1 = NULL, p2 = NULL; //在vs中必须初始化为空,否则乱指
	p2 = head1;
	int a;
	char b[20];
	
	while (1)
	{
		scanf("%d %s", &a, b);
		if (a == 0)
			break;
		p1 = (Node*)malloc(sizeof(Node));  //首先申请空间
		strcpy(p1->b, b);   //传入字符串b的数据
		p1->a = a;      //传入整形数据a
		p2->next = p1;
		p2 = p1;
	}
	p2->next = NULL;   //最后一个结点的指针域为空
}

(2)头插法

缺点:数据读入顺序和链表中结点顺序相反

void Creat_head(LinkList head)
{
	LinkList head2 = NULL, p1 = NULL, p2 = NULL;
	p2 = head2;
	int a;
	char b[20];
	while (1)
	{
		scanf("%d %s", &a, b);
		if (a == 0)
			break;
		p1 = (Node*)malloc(sizeof(Node));
		strcpy(p1->b, b);
		p1->next = head->next;  //将新建立结点指向头的下一个结点
		head->next = p1;  //head的指针域指向新建立的结点
	}
}

(3)插入结点到第几个结点的位置


LinkList Insert(LinkList head, int i)
{
	Node* p , * s;
	s = (Node*)malloc(sizeof(Node));
	int a;
	char b[20];
	scanf("%s", p->b);
	scanf("%d",&p->a);
	if (i == 1)
	{
		s->next = head;
		head = s;
	}
	else
	{
		int j = 1;
		p = head;
		while (j < i - 1 &&p) //遍历到插入位置的前一个结点
		{
			p = p->next;
			j++;
		}
		if (p)
		{
			s->next = p->next;
			p->next = s;
		}
	}
	return head;
}

2. 删

LinkList Delete(LinkList head, int n)
{
	Node* p = head, * q;
	int n;
	scanf("%d", &n);
	if (head == NULL)
	{
		printf("the n is error!");
		return;
	}
	if (n == 1)  //删除第一个结点的特殊情况
	{
		q = head;
		head = head->next;
		free(q);
	}
	else
	{
		int j = 1;
		while (j < n - 1 && p)
		{
			p = p->next;
			j++;
		}
		if (p == NULL || p->next == NULL) //p为需删除结点的前一个,
                                            所以如果删除的前一个或者删除的结点为空,则错误
		{
			printf("the n is error!");
		}
		else
		{
			q = p->next;
			p->next = q->next;
			free(q);
		}
	}
	return head;
}

3. 查 

LinkList Search(LinkList head)
{
    int x;
    LinkList p;
    scanf("%d", &x);
    while(p != NULL && p->a != NULL)
    {
        p = p->next;  //没找到查询的结点继续向下找
    }
    if (p == NULL)
    {
        printf("没有找到该点!");
        return NULL;
    }
    return head;
}

4. 改

void Modify(LinkList head)
{
	LinkList p = Search(head); //调用“查”的程序
	if (p == NULL)
	{
		return;
	}
	int val;
	scanf("%d", &val);
	p->a = val;  //修改数据
	return;   
}

5. 逆置

void Reverse(LinkList head)
{
	Node* p, * q;
	p = head->next;
	while (p)
	{
		q = p->next;
		p->next = head->next;
		head->next = p;
		p = q;
	}
}

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值