线性表根据存储结构可以分为链式存储和顺序存储。
顺序存储实际上可以理解为结构体数组,要求逻辑上相邻的元素在物理上也是相邻的;
而链式存储没有这样的要求,这样就便于元素的插入删除操作(顺序存储在插入删除操作时需要移动大量的元素)。
定义单链表结点 typedef struct Node{ int element; //结点元素 struct Node* next; //结点指针 }Node,*LinkList; LinkList CreateList_head(); LinkList CreateList_tail(); void print(LinkList L);
在进行创建链表的时候有两种方法,一种称之为尾插法另一种就是头插法;
顾名思义,尾插法就是将结点插在单链表的尾部,此时就需要一个指向单链表尾结点的指针(可以在结点定义的时候就直接多一个尾指针r域);
头插法就是将结点插在单链表的头不过这样的话单链表的结点元素顺序就是相反的;
#include<stdio.h> #include<stdlib.h> #include<iostream> #include "LinkList.h" using namespace std; //头插法创建链表 LinkList CreateList_head(){ LinkList L = (Node*)malloc(sizeof(Node)); //创建头结点 L->next = NULL; int x; cin>>x; while(x!=9999){ //输出9999结束 Node* p = (Node*)malloc(sizeof(Node)); p->element = x; p->next = L->next; L->next = p; cin>>x; } return L; } LinkList CreateList_tail(){ LinkList L = (Node*)malloc(sizeof(Node)); //创建头结点 L->next=NULL; Node* r = L; //一个指向尾结点的指针 int x; cin>>x; while(x!=9999){ Node* p = (Node*)malloc(sizeof(Node)); p->element = x; p->next = NULL; //使当前结点作为尾结点后next域为NULL r->next = p; r = p; cin>>x; } return L ; } //输出单链表结点 void print(LinkList L){ Node* p = L->next; cout<<"the LinkList is:"<<endl; while(p){ cout<<p->element<<endl; p=p->next; } } //链表的逆置 //使用头插法进行单链表的逆置操作 void reverse(LinkList &L){ Node* r = L->next; //r指针指向单链表的第一个结点 L->next = NULL; //将头结点脱链 while(r){ //r指向单链表的下一个待链接结点 Node* p = r->next; //p指向r的下一个结点在一次链接完成后赋值给r防止断链 r->next = L->next; //将r指向的结点新的逆置单链表中 L->next = r ; r = p; //暂存的p结点指针赋值给r,进入下一轮循环 } }