单链表 双链表
创建单链表
struct Link{
int elem; //数据域
struct Link *next;//指向下一个节点的指针域
}
不带头的单链表:
第一个保存数据的节点 : 首元节点
指向第一个数据的指针: 头指针
//创建不带头的单链表
#include<stdio.h>
#include<stdlib.h>
//1.声明一个头指针
//2.创建多个存储数据的节点,时刻保持指向关系
typedef struct Link{
int elem; //数据域
struct Link *next;//指针域
}link;
link *initLink(){
link *p=NULL; //头指针
link *temp = (link *)malloc(sizeof(link));
temp->elem =1;
temp->next = NULL;
p = temp;
for(int i=2;i<5;i++){
link *a = (link *)malloc(sizeof(link));
a->elem =i;
a->next =NULL;
temp->next =a;
temp = temp->next; //后移
}
return p;
}
void display(link *p){
link *temp = p;
while(temp){
printf("%d",temp->elem;
temp = temp->next;
}
printf("\n");
}
带头的单链表:
第一个不保存数据的节点:头节点
//创建带头的单链表
#include<stdio.h>
#include<stdlib.h>
typedef struct Link{
int elem;
struct Link *next;
}link;
link *initLink(){
link *temp= NULL;
link *p = (link *)malloc(sizeof(link));
p->next =NULL;
p->elem = NULL;
temp->p;
for(int i=1;i<5;i++){
link *a =(link *)malloc(sizeof(link));
a->elem = i;
a->next = NULL;
temp->next = a;
temp = temp->next;
}
return p;
}
void display(link *p){
link *temp = p;
while(temp->next){
temp = temp->next;
printf("%d ",temp->elem;
}
printf("\n");
}
int main(){
link *p = initLink();
display(p);
}
单链表的基本操作
以不带头的单链表为例
链表的插入
1.链表的插入:头插、尾插、中间插
#include<stdio.h>
#include<stdlib.h>
typedef struct Link{
int elem;
struct Link *next;
}link;
link *initLink(){
link *p=NULL; //头指针
link *temp = (link *)malloc(sizeof(link));
temp->elem =1;
temp->next = NULL;
p = temp;
for(int i=2;i<5;i++){
link *a = (link *)malloc(sizeof(link));
a->elem =i;
a->next =NULL;
temp->next =a;
temp = temp->next; //后移
}
return p;
}
// int add 添加的新元素的位置 int elem 插入元素
link *insertElem(link *p,int elem,int add){
link *temp =p;
//移动指针 到插入位置的上一个节点
for(int i=1;i<add;i++){
temp = temp->next;
if(temp == NULL){
printf("位置不合法");
return p;
}
}
link *a =(link *)malloc(sizeof(link));
a->elem = elem;
if(add == 1){
a->next = temp;
p = a;
}else{
a->next = temp->next;
temp->next = a;
}
return p;
}
void display(link *p){
link *temp = p;
while(temp){
printf("%d ",temp->elem);
temp = temp->next;
}
printf("\n");
}
int main(){
link *p =initLink();
//display(p);
link *p1 = insertElem(p,50,1);
display(p1);
}
链表的删除
1.将该节点摘下来,让该节点的前一个节点的指针域指向该节点的下一个节点;
2.将摘下来的节点释放掉(free())
link *delLink(link *p,int del){
link *temp =p;
//移动到要删除元素的前一个节点
for(int i=0; i<del-1;i++){
temp = temp->next;
if(temp->next ==NULL){
printf("指针移动到了最后一个节点!");
return p;
}
}
link *a = temp->next;
temp->next = temp->next->next;
free(del);
return p;
}
int main(){
link *p =initLink();
display(p);
link *p2 = delLink(p,3);
display(p2);
}
链表的查找
int selectElem(link *p ,int elem){
link *temp =p;
int i=1;
while(temp->next!=NUll){
if(temp->elem = elem){
return i;
}
temp = temp->next;
i++;
}
return 0;
}
链表的更新元素
// 知道位置更新元素
link *updateLink(link *p,int newElem,int add){
link *temp =p;
for(int i = 1;i < add;i++){
temp = temp->next;
if(temp->next ==NULL){
printf("位置不合法");
}
}
temp->elem = newElem;
return p;
}
//不知道位置更新元素,将oldElem旧元素更新为newElem新元素
link *update(link *p,int newElem,int oldElem){
link *temp = p;
int add = selectElem(p,oldElem);
for(int i = 1;i < add;i++){
temp = temp->next;
if(temp->next ==NULL){
printf("位置不合法");
}
}
temp->elem = newElem;
return p;
}
完整的代码
#include<stdio.h>
#include<stdlib.h>
typedef struct Link{
int elem;
struct Link *next;
}link;
link *initLink(){
link *p=NULL; //头指针
link *temp = (link *)malloc(sizeof(link));
temp->elem =1;
temp->next = NULL;
p = temp;
for(int i=2;i<5;i++){
link *a = (link *)malloc(sizeof(link));
a->elem =i;
a->next =NULL;
temp->next =a;
temp = temp->next; //后移
}
return p;
}
// int add 添加的新元素的位置 int elem 插入元素
link *insertElem(link *p,int elem,int add){
link *temp =p;
//移动指针 到插入位置的上一个节点
for(int i=1;i<add-1;i++){
temp = temp->next;
if(temp == NULL){
printf("位置不合法1");
return p;
}
}
link *a =(link *)malloc(sizeof(link));
a->elem = elem;
a->next = temp->next;
temp->next = a;
return p;
}
void display(link *p){
link *temp = p;
while(temp){
printf("%d",temp->elem);
temp = temp->next;
}
printf("\n");
}
//删除
link *delLink(link *p,int del){
link *temp =p;
//移动到要删除元素的前一个节点
for(int i=0; i<del-1;i++){
temp = temp->next;
if(temp->next ==NULL){
printf("指针移动到了最后一个节点!");
return p;
}
}
link *a = temp->next;
temp->next = temp->next->next;
free(del);
return p;
}
//查找
// 知道位置更新元素
link *updateLink(link *p,int newElem,int add){
link *temp =p;
for(int i = 1;i < add;i++){
temp = temp->next;
if(temp->next ==NULL){
printf("位置不合法");
}
}
temp->elem = newElem;
return p;
}
//不知道位置更新元素,将oldElem旧元素更新为newElem新元素
link *update(link *p,int newElem,int oldElem){
link *temp = p;
int add = selectElem(p,oldElem);
for(int i = 1;i < add;i++){
temp = temp->next;
if(temp->next ==NULL){
printf("位置不合法");
}
}
temp->elem = newElem;
return p;
}
//主函数
int main(){
link *p =initLink();
display(p);
link *p1 = insertElem(p,3,50);
display(p1);
}
双向循环链表
双向链表的结构
typedef struct doubleList{
int data;//数据域
struct doubleList *prev;
struct doubleList *next;
}doubleList;
双向链表的操作
#includ<stdio.h>
#include<stdlib.h>
typedef struct doubleList{
int data;//数据域
struct doubleList *prev;
struct doubleList *next;
}doubleList;
//创建链表的函数
doubleList *createList(){
doubleList *head,*p,*q;
int n,x;
//创建头节点
head =(doubleList *) malloc(sizeof(doubleList));
head->prev = head;
head->next = head;
p = head;
printf("输入元素的个数");
scanf("%d",&n);
for(int i=0;i<n;i++){
printf("请输入第%d个元素",(i+1));
scanf("%d",&x);
q =(doubleList *) malloc(sizeof(doubleList));
q->data = x;
p->next = q;
head->prev =q; //头节点的上一个指向最后一个
q->prev = p;
q->next = head;//最后一个的下一个指向第一个
p = q;
}
return head;
}
//遍历链表
void display(doubleList *head){
doubleList *temp = head;
temp = temp->next;
while(temp!= head){
printf("%d",temp->next);
temp = temp->next;
}
printf("\n");
}
//统计元素个数
int lengthList(doubleList *head){
doubleList *temp = head;
int count =0;
temp = temp->next;
while(temp!= head){
count++;
temp = temp->next;
}
return count;
}
//插入数据
//在第i个元素之前插入数据data
doubleList *insertList(doubleList *head,int i,int newData){
doubleList *temp = head;
doubleLIst *q;
temp = temp->next;
i--;
while(i--){
temp = temp->next;
}
q =(doubleList *) malloc(sizeof(doubleList));
q->data = newDate;
p->prev->next =q;
q->prev = p->prev;
q->next = p;
p->next = q;
return head;
}
//删除第i个位置的元素
void delList(doubleList *head,int i){
doubleList *temp = head;
temp = temp->next;
i--;
while(i--){
temp = temp->next;
}
temp->prev->temp = temp->next;
temp->next->prev = temp->prev;
free(temp);
}
//删除值为x的元素
void delList_x(doubleList *head,int i){
doubleList *temp = head;
doubleList *q;
temp = temp->next;
while(temp!=head){
if(temp->data == x){
q = temp->next;
temp->prev->temp = temp->next;
temp->next->prev = temp->prev;
free(temp);
temp = q;
}else{
temp = temp->next;
}
}
}
//排序
void sortList(doubleList *head){
doubleList *temp = head;
doubleList *p;
temp = temp->next;
for(;temp!=head;temp=temp->next){
for(p=temp->next;p!=head;p=p->next){
if(temp->data < p->data){
int a = temp->data;
temp->data = p->data;
p->data = a;
}
}
}
}
int main(){
doubleList *head = createList();
display(head);
//查找
int len = lengthList(head);
printf("%d",len);
//添加
head = insertList(head,3,100);
display(head);
//删除第i个元素
delList(head,3);
display(head);
//删除x的元素
delList_x(head,4);
display(head);
//排序
sortList(head);
}