尾插法
#include<stdio.h>
#include<malloc.h>
//尾插法
struct list{
int data;
struct list *next;
};
typedef struct list node;
typedef node *link;
int main(){
link rail,head;
int i,num;
//输入链表中的元素
head = (link) malloc (sizeof(node));
rail = head; //head为头指针
printf("input 5 numbers: \n");
for(int i =0;i < 5;i++){
scanf("%d",&num);
link temp = (link) malloc(sizeof(node));
temp->data = num;
rail->next = temp;
rail = temp; //rail始终指向最后一个结点
}
rail->next = NULL; //尾结点指针设为空
head = head->next; //跳过头指针的数值域,因为头指针没有数值
//输出链表
while (head != NULL)
{
printf("%d\n", head->data);
head = head->next;
}
return 0;
}
头插法
#include<stdio.h>
#include<malloc.h>
struct list{
int data;
struct list *next;
};
typedef struct list node;
typedef node *link;
int main(){
link ptr,head;
int i,num;
//输入链表中的元素
head = (link) malloc (sizeof(node)); //head为头指针
head->next = NULL;
printf("input 5 numbers: \n");
for(int i = 0;i < 5;i++){
scanf("%d",&num);
ptr = (link) malloc(sizeof(node));
ptr->data = num;
ptr->next = head->next; //先让新结点指向头指针指向的的结点(空结点)
head->next = ptr; //然后才能让头指针指向新结点.
}
head = head->next; //跳过头结点输出,因为头结点data域没有值
//输出链表
while (head != NULL)
{
printf("%d\n", head->data);
head = head->next;
}
return 0;
}
单链表的常用操作
//1.单链表的初始化
//2.判空操作
//3.遍历操作
//4.求单链表长度
//5.按值查找
//6.按位查找
//7.插入操作
//8.1根据a[n]元素建立单链表 :头插法
//8.2根据a[n]元素建立单链表 :尾插法
//9.删除操作
//10.销毁单链表
//11.1 反转链表 方法1
//11.2 反转链表 方法2
#include<stdio.h>
#include<malloc.h>
#include<bits/stdc++.h>
using namespace std;
typedef int DataType;
typedef struct Node{
DataType data;
struct Node *next;
}Node;
//1.单链表的初始化
Node *InitList(){
Node * first = (Node *)malloc(sizeof(Node)); //生成头结点
first->next = NULL; //头结点指针域置空
return first;
}
//2.判空操作
int Empty(Node * first){
if(first->next == NULL) return 1;
else return 0;
}
//3.遍历操作
void PrintList(Node *first){
Node *p = first->next; //工作指针p初始化
while(p!=NULL){
printf("%d ",p->data);//输出结点的数据域,假设为int型
p = p->next; //工作指针p后移,注意不能写成p++
}
printf("\n");
}
//4.求单链表长度
int Length(Node *first){
Node *p = first->next; //工作指针p初始化
int count = 0; //累加器count初始化
while(p!=NULL){
p = p->next;
count ++;
}
return count;
}
//5.按值查找
int Locate(Node *first,DataType x){
Node *p = first->next; //工作指针p初始化
int count = 1; //累加器count初始化
while (p!=NULL){
if(p->data == x) return count; //查找成功,结束函数并返回序号
p = p->next;
count ++;
}
return 0; //退出循环表示查找失败
}
//6.按位查找
int Get(Node *first,int i,DataType *ptr){
Node *p = first->next;
int count = 1;
while(p!=NULL&&count<i){
p = p->next;
count ++;
}
if(p == NULL) {printf("位置错误,查找失败\n");return 0;}
else{* ptr = p->data; return 1;}
}
//7.插入操作
int Insert(Node *first,int i,DataType x){
Node *s = NULL,*p = first; //工作指针p初始化为指向头节点
int count = 0;
while(p!=NULL && count < i-1){//查找第i-1个结点
p = p->next;
count++;
}
if(p == NULL){printf("位置错误,插入失败\n"); return 0;}
else{
s = (Node *)malloc(sizeof(Node));
s->data = x;
s->next = p->next; //申请一个结点,数据域为x
p->next = s; //将结点s插入到结点p之后,注意"先右后左"
return 1;
}
}
//8.1根据a[n]元素建立单链表 :头插法
Node * CreatList_H(DataType a[],int n){
Node *s = NULL;
Node *first = (Node*)malloc(sizeof(Node));
first->next = NULL; //初始化头节点
for(int i = 0;i < n;i ++){
s = (Node *)malloc(sizeof(Node));
s->data = a[i]; //为每个数组元素建立一个结点
s->next = first->next; //将结点s插入到头节点之后
first->next = s;
}
return first;
}
//8.2根据a[n]元素建立单链表 :尾插法
Node * CreatList_R(DataType a[],int n){
Node *s = NULL,*last = NULL;
Node *first = (Node *)malloc(sizeof(Node)); //生成头节点
last = first; //尾指针初始化
for(int i = 0;i < n;i++){
s = (Node *)malloc(sizeof(Node));
s->data = a[i]; //为每个数组元素建立一个结点
last->next = s; //将结点s插入到终端结点之后
last = s; //尾指针后移,始终指向终端结点
}
last->next = NULL; //单链表建立完毕,将终端结点的指针域置为空
return first;
}
//9.删除操作
int Delete(Node *first,int i,DataType *ptr){
Node *p = first,*q = NULL;
int count = 0;
DataType x;
while(p!=NULL && count < i-1){ //查找第i-1个结点
p = p->next; //p最终指向第i-1个结点
count ++;
}
if(p==NULL || p->next==NULL){ //p结点或p的后继结点不存在
printf("位置错误,删除失败\n"); return 0;
}else{
q = p->next; //q指向p的后一个结点,即第i个结点
* ptr = q->data; //存储被删除结点和被删除的元素
//printf("q->data=%d\n",q->data);
p->next = q->next; //摘链
free(q);
return 1;
}
}
//10.销毁单链表
void DestroyList(Node *first){
Node *p = first;
while(first!=NULL){ //依次释放每一个结点,包括头结点
first = first->next;
free(p);
p = first;
}
}
/* 11.1 反转链表 方法1
// 图文解释: https://blog.csdn.net/qq_42351880/article/details/88637387
Node *reverseList(Node* head) {
Node *newHead = NULL;
Node *node;
while (head != NULL) {
//1. 对之前的链表做头删
node = head;
head = head->next;
//2. 对新链表做头插
node->next = newHead;
newHead = node;
}
return newHead;
}
*/
//11.2 反转链表 方法2
Node *reverseList(Node* head) {
if (head == NULL) {
return NULL;
}
Node *p0 = NULL;
Node *p1 = head;
Node *p2 = head->next;
while (p1 != NULL) {
p1->next = p0;
p0 = p1;
p1 = p2;
if (p2 != NULL) {
p2 = p2->next;
}
}
return p0;
}
int main(){
int r[5] = {1,2,3,4,5},i,x;
Node *first = NULL;
Node *head = NULL;
first = NULL;
first = CreatList_R(r,5); //根据a[n]元素建立单链表 :尾插法
printf("当前线性表的数据为: ");
PrintList(first); //尾插法输出当前线性表为1 2 3 4 5,头插法顺序相反
Insert(first,2,8); //在第二个位置插入值为8的结点
printf("执行插入后数据为:");
PrintList(first); //输出插入后链表 1 8 2 3 4 5
printf("当前链表长度为: %d\n",Length(first)); //输出链表长度为6
printf("请输入查找的元素值: ");
scanf("%d",&x);
head = first; //head指向first链表
i = Locate(head,x); /*cout<<i; 测试是否返回值成功 */
if(i != NULL) printf("元素%d的位置为:%d\n",x,i);
else printf("单链表中没有元素%d\n",x);
printf("请输入要删除第几个元素: ");
scanf("%d",&i);
if(Delete(head,i,&x) == 1){//删除第i个元素
printf("删除的元素值是%d,执行删除操作后数据为:\n",x);
PrintList(head);
}else printf("删除失败\n");
printf("执行逆置后数据为:");
head = reverseList(first); //逆转first链表
while( Length(head) ){ //输出逆转链表,因为逆转后以后一个结点类似头结点,值域为空.所以不能用常规的打印方法,否则会多打印出一个值
printf("%d ",head->data);
head = head->next;
}
DestroyList(head); //释放单链表
return 0;
}