C/C++数据结构与算法笔记1(单向链表)

C/C++数据结构与算法笔记1(单向链表)

笔记来自CSDN课程 C/C++ 数据结构与算法 (王桂林)

定义头文件 list.h

#infndef _LIST_H_
#define _LIST_H_

typedef struct _Node
{
	int data;
	struct _Node * next;
	
}Node;

Node * createList();
void insertList(Node * head, int data);
void travereList(Node * head);
int lenList(Node * head);
Node * searchList(Node * head, int find);
void deleteList( Node * head, Node * pfind);
void popSortList(Node * head);
void reverseList(Node * head);
void destroyList(Node * head);

#endif // LIST_H

基本函数 list.c

创建链表,插入元素,遍历元素,取链表长度,删除元素,排序,逆序,删除链表

#include "list.h"

//带有头节点的链表,创建新链表(空)
Node * createList()  //创建
{
	Node * head = (Node *)malloc(sizeof(Node));
	if (head)
	{
		head -> next = NULL
	};
	return head;
}

//指向-->就是代表存储的地址
void insertList(Node *head, int data) // 插入
{
	Node * cur = (Node *)malloc(sizeof(Node));
	cur -> data = data;
	cur -> next = head -> next ;
	head -> next = cur;
}

void travereList(Node * head) // 遍历
{
	head = head -> next;
	while(head)
	{
		print("%2d",head->data); //cout 
		head = head -> next;
	}
}

int lenList(Node * head) // 取链表长度
{
	int count = 0 ;
	head = head -> next;
	while(head)
	{
		count ++ ;
		head = head -> next;
	}
	return count;
}

Node * searchList(Node * head, int find) //寻找元素,返回位置
{
	head = head->next;
	while(head)
	{
		if(head->data == find)
			break;
		head = head->next;
	}
	return head;
}


Node deleteList(Node* head, Node* pfind) // 删除元素 
{	
	while(head -> next != pfind)
	{
		head = head -> next ;
	}
	head -> next = pfind -> next;
	free(pfind); // 通过遍历来完成
	
}

Node deleteList2(Node* head, Node* pfind) //删除元素  取巧的方法:交换位置得到前驱
{	if(pfind -> next == NULL){
		while(head -> next != pfind)
		{
			head = head -> next ;
		}
		head -> next = pfind -> next;
		free(pfind); 
	}
 	else{
		pfind -> data = pfind -> next -> data;
		Node * t = pfind -> next;
		pfind->next=t->next;
		free(t);		
	}
}

void popSortList(Node * head) //冒泡排序 交换数据法
{
	Node * p , * q;
	int len = lenList(head);
	for(int i = 0; i<len-1; i++)
	{
		p = head -> next;
		q = p -> next;
		for(int j=0;j<len-1-i;j++)
		{
			if(p->data > q->data)
			{
				p->data ^= q->data; //XOR
				q->data ^= p->data; 
				p->data ^= q->data;
			}
			p = p->next;
			q = q->next;
		}
	}
}


void popSortList2(Node * head) //冒泡排序 交换指针法
{
	Node * p , * q;
	int len = lenList(head);
	for(int i = 0; i<len-1; i++)
	{
		pre = head ; //定义前驱位置
		p = head -> next;
		q = p -> next;
		for(int j=0;j<len-1-i;j++)
		{
			if(p->data > q->data)
			{
				pre -> next = q; //前驱连q
				p -> next = q -> next; //q连p
				q -> next = p; // p连到后续
				
				pre = q; //保持原队列往后走
				q = p -> next;
				continue; 
			}
			
				pre = pre -> next; //更新到下一个比较
				p = p -> next;
				q = q -> next; 
			
		}
	}
}

void reverseList(Node * head)
{
	Node *h = head -> next;
	head -> next = NULL;
	Node *t ;
	while(h) //把原单链表中的结点依次进行逆序链接。
	{
		t=h; //t 指向待处理的结点。
		h=h->next; // h 指向下一个待逆序的结点。
         //将 t 结点插入到已逆序单链表的表头。
		t->next = head ->next;
		head->next = t;


		//或者用下面方法
		//t = h -> next;
		//h->next = head -> next;
		//head->next = h;
		//h = t;	
	}
}

void destroyList(Node * head) //删除链表
{
	Node *t;
	while(head)
	{
		t = head -> next;
		free(head);
		head = t;
	}
}

其中逆序用到了头插法,详见图解链接(link

测试范例 main.c

#include <time.h>
#include <stdlib.h>
#include "list.h"
#include <stdio.h>

int main()
{
    Node * head = createList(); //创建
    travereList(head);
    strand(time(NULL));
    for(int i=0;I<10;i++)
    {
        insertList(head, rand()%100) ; //插入
    }
    travereList(head); //遍历

    int len = lenList(head);
    printf("len = %d \n",len); //取长

    Node * pfind = searchList(head,8); //查找
    if (pfind ! = NULL)
    {
        printf("find in the list! \n");
        deleteList(head,pfind); //删除元素
    }
   
    printf("after sort: \n");
    popSortList(head); //排序
    travereList(head);

    reverseList(head); //逆序
    travereList(head);

    destroyList(head); //删除链表

    return 0;
}

上述方法采用C编写,C++可以通过定义类(CLASS),语法上略有不同,核心思路一样,详见后续博文。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值