基于链表的一些操作

定义结构体

typedef struct node {
	int data;
	node *next;
}Node, *pNode; 

创建链表的几种方式

一、头插法

在链表头部插入新结点建立单链表的方法简称头插法。
示意图:
在这里插入图片描述

代码:


void createlist (Node *h)
{
    int num;
    while (num != 0) {
       scanf("%d", &num);
       Node *p =(Node*)malloc(sizeof(Node));
       p->data = num;
       p->next = h->next;
       h->next = p;
   }
}

二、尾插法:

在单链表尾部插入新结点建立单链表的方法简称尾插法。
示意图:
在这里插入图片描述
代码实现:

void createlist(Node *h)
{
    int num;
    while (num != 0) {
       scanf("%d",&num)
       node *p = (Node*)malloc(sizeof(Node));
       p->data = num;
       h->next = p;
       h = p;
    }
    h->next = NULL;
}

增删查改

一、增

void Insert(Node *h, int i) //i为插入的位置
{
	Node *p = head, *s;
	int j = 0;
	while (j < i - 1 && p) {
		p = p->next;
		j++;
	}
	if (p) {
		s = (Node *)malloc(sizeof(Node));
		scanf("%d", &s->data);
		s->next = p->next;
		p->next = s;
	}
}

二、删

void Delete(Node *head)
{
	int pos;
	printf("请输入要删除的数据所在位置:\n");
	scanf("%d", &pos); 
	Node *p = head, *s;
	int j = 0;
	printf("删除第%d个数据\n", pos);
	while (j < pos - 1 && p) {
		p = p->next;
		j++;
	}
	if (p == NULL || p->next == NULL) {
		printf("the pos if error");
	} else {
		s = p->next;
		p->next = s->next;
		free(s);
	}
}

三、查

void Search(Node *head)
{
	int data;
	printf("请输入你要查询的数据:");
	scanf("%d", &data);
	Node *p = head->next;
	while (p) {
		if (p->data != data){
			p = p->next;
		} else {
			printf("数据为:%d",p->data);
			break;	
		} 
		if (p == NULL) {
			printf("没有找到数据为%d的结点!",data);
		} 
	}
}

四、改

void Change(Node *head)
{
	Node *p;
	p = head->next;
	int i, j = 0;
	printf("请输入你要修改的结点位置:\n");
	scanf("%d", &i);
	while (j < i - 1 && p) {
		p=p->next;
		j++;
	}
	if(p) {
		printf("请输入修改后的数据:\n");
		int data;
		scanf("%d", &data);
		p->data = data;
	}
}

快慢指针

所谓「快慢指针」是指设定两个指针,其中快的指针的移动速度是慢的指针的移动速度的两倍;“快慢指针”方法主要用来解决两类问题,即“判断一个链表是否为循环链表”以及“寻找一个有序链表的中位数”(回文链表的判断)。

代码:

	Node *fast = head;
	Node *slow = head;
	while (fast != NULL && fast->next!=NULL) {
		slow = slow->next;
		fast = fast->next->next;
	}

链表的反转

一、局部反转

	Node *fast = head;
	Node *slow = head;
	while(fast != NULL && fast->next!=NULL){
		slow = slow->next;
		fast = fast->next->next;
	}
	Node *secondhead = NULL;
	Node *second = slow->next;
	slow->next = NULL;
	while (second != NULL) {
		Node *tmp = second->next;
		second->next = secondhead;
		secondhead = second;
		second = tmp;
	}
	while (secondhead != NULL && head->next->data == secondhead->data) {
        head = head->next;
        secondhead = secondhead->next;
    }

二、新建链表法

运用头插法将原链表中的节点复制到新链表中。原链表中的最后一个节点到新链表的第一个节点,以此类推,得到反转后的链表。

struct node* reverseList(Node *head){

    Node* Newhead;//定义一个头节点
    Newhead = (Node*)malloc(sizeof(Node));
    Node *p = head, *q, *n; //p指向原链表的节点,q为临时节点,n为新链表中的节点
    n = Newhead;
    n->next = NULL;
    while(p) {
        q = p->next;//临时节点存p节点的下一个
        p->next = n->next; 
        n->next = p;//
        p = q;
    }
    return Newhead->next;
}

三、三指针法

定义三个指针,从头遍历,三个指针分别指向三个节点。反转前两个节点,即使第二个节点指向第一个节点,然后依次向后移动指针,知道第二个指针指向空时停止。

struct node* reverseList(Node *head) {
	Node *p,*q,*nexttmp;
	p = NULL;
	q = head;
	nexttmp = NULL;
	while (q) {
		nexttmp = q->next;  //将q指向的下一个保存在nexttmp中
		q->next = p;   //反转
		p = q;
		q = nexttmp; //指针向后移动
	}
	return p;
}


有关链表的例题:

例题一

判断一个链表是否为循环链表

bool IsCLinkList(Node *head)
{
    if (!head) {
        return false;
    }
    Node *fast, *slow;
    fast = slow = head;
    while (1) {
        if (!fast || !fast->next) {
            return false;
        } else if (fast == slow || fast->next==slow){
            return true;
        } else {
            slow = slow->next;
            fast = fast->next->next;
        }
    }
}

例题二

题目:3. 请判断一个链表是否为回文链表。
自己创建输入输出链表
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true

#include<stdio.h>
#include<malloc.h>

typedef struct node{
	int data;
	struct node *next;
}Node, *pNode;

struct node* InitList()
{
	pNode head;
	head = (Node *)malloc(sizeof(Node));
	head->next=NULL;
	return head;
}
void CreateList(pNode head){
	Node *r, *s;
	r=head;
	int data;
	while (1) {
		printf("请输入数据:");
		scanf("%d", &data);
		if (data == 0) {
			break;
		}
		s = (Node *)malloc(sizeof(Node));
		s->data = data;
		if (head == NULL) {
			head = s;
		} else {
		    r->next = s;
		    r = s;
		}
	}
	r->next = NULL;
}
void OutPut(pNode head)
{
	Node *p;
	p=head->next;
	while (p) {
		printf("数据为:%d\n", p->data);
		p = p->next;
	}
}
void panduan(pNode head){
	Node *p = head;
	if (head == NULL || head->next == NULL) {
		printf("true");
	}
	Node *fast = head;
	Node *slow = head;
	while (fast != NULL && fast->next!=NULL) {
		slow = slow->next;
		fast = fast->next->next;
	}
	Node *secondhead = NULL;
	Node *second = slow->next;
	slow->next = NULL;
	while (second != NULL) {
		Node *tmp = second->next;
		second->next = secondhead;
		secondhead = second;
		second = tmp;
	}
	while (secondhead != NULL && head->next->data == secondhead->data) {
        head = head->next;
        secondhead = secondhead->next;
    }
    
    if (secondhead == NULL) {
        printf("true");
    } else {
        printf("false");
    }
}
int main()
{
	pNode ha;
	ha = InitList();
	CreateList(ha);
	panduan(ha);
	return 0;
}

例题三

题见leetcode1721

这里是引用

struct ListNode* swapNodes(struct ListNode* head, int k){
    struct ListNode *p = head, *q = head, *s;
    if (head == NULL || k <= 0) {
        return head;
    }
    for (int i = 1; i < k; i++) {
        p = p->next;
    }
    if (p == NULL) {
        return head;
    }
    s = p->next;
    while (s != NULL) {
        q = q->next;
        s = s->next; 
    }
    int temp = p->val;
    p->val = q->val;
    q->val = temp;
    return head;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值