关于循环单向链表和循环双向链表请将鼠标移步 此处点击
1.顺序表
实现代码:
//#pragma once //作为头文件时加上这行
#include<stdio.h>
#define LIST_MAXSIZE 50 //顺序表最大能存的元素个数
typedef int DataType ; //元素的数据类型
typedef struct {
DataType list[LIST_MAXSIZE];
int size; //顺序表的元素数量
}SeqList;
/*初始化顺序表,将L->size置为0*/
void ListInit(SeqList* L);
/*判断顺序表是否非空*/
int ListNotEmpty(SeqList* L);
/*在下标为i[0,size]的位置处插入一个元素x,位于该处及该处后的元素依次后移,成功返回1,失败返回0*/
int ListInsert(SeqList* L, int i,DataType x);
/*将下标为i[0,size]的位置元素删除,并把值保存在x中,位于该元素后的依次前移,成功返回1,失败返回0*/
int ListDelete(SeqList* L, int i, DataType *x);
/*放问下标为i[0,size]的位置元素,并把值保存在x中,成功返回1,失败返回0*/
int ListGet(SeqList* L, int i, DataType *x);
void ListInit(SeqList* L)
{
L->size = 0;
}
int ListNotEmpty(SeqList* q)
{
if (q->size != 0)return 1;
else return 0;
}
int ListInsert(SeqList* L, int i, DataType x)
{
int j=L->size;
if (i < 0 || i > L->size) {
printf("插入位置i,参数不合法\n");
return 0;
}
if (L->size == LIST_MAXSIZE) {
printf("顺序表已满,无法插入\n");
return 0;
}
while (j > i) //把原位于i及之后的位置上的元素右移
{
L->list[j] = L->list[j - 1];
j--;
}
L->list[i] = x; //把x插进去
L->size++;
return 1;
}
int ListDelete(SeqList* L, int i, DataType *x)
{
int j = i + 1; //记录i元素后一个的下标
if (!ListNotEmpty(L)) {
printf("顺序表中元素为空,无元素可删除。\n");
return 0;
}
if (i < 0 || i >= L->size) {
printf("参数不合法,删除失败。\n");
return 0;
}
*x = L->list[i]; //把删除的元素赋值给*x
while(j<L->size)
{
L->list[j - 1] = L->list[j]; //将位置i后的元素前移
j++;
}
L->size--;
return 1;
}
int ListGet(SeqList* L, int i, DataType *x)
{
if (!ListNotEmpty(L)) {
printf("顺序表中元素为空,无元素可取。\n");
return 0;
}
if (i < 0 || i >= L->size) {
printf("参数不合法,取出失败。\n");
return 0;
}
*x = L->list[i];
return 1;
}
测试函数:
void test()
{
int i, x;
SeqList L;
ListInit(&L);
for (i = 0; i < 10; i++)
ListInsert(&L, i, i);
printf("将下标为5处的元素删除\n");
ListDelete(&L, 5, &x);
printf("被删除的元素为:%d\n", x);
printf("插入元素10到下标为5处:\n", x);
ListInsert(&L, 5, 10);
printf("将链表输出\n");
for (i = 0; i < L.size ; i++)
{
ListGet(&L, i, &x);
printf("%d ", x);
}
}
运行结果:
2.单向链表
实现代码:
//#pragma once //作为头文件时加上这行
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef int DataType;
typedef struct Node
{
DataType data;
struct Node *next;
}LinkedList;
/*以下的第几个结点都不包括头节点,即头结点不计入下标*/
/*初始化链表*/
void ListInit(LinkedList* head);
/*判断链表是否非空*/
int ListNotEmpty(LinkedList* head);
/*返回链表元素个数*/
int ListLength(LinkedList* head);
/*在下标为i[0,size]的位置处插入一个元素x,位于该处及该处后的元素依次后移,成功返回1,失败返回0*/
int ListInsert(LinkedList* head, int i, DataType x);
/*将下标为i[0,size]的位置元素删除,并把值保存在x中,位于该处元素后的元素依次前移,成功返回1,失败返回0*/
int ListDelete(LinkedList* head, int i, DataType *x);
/*放问下标为i[0,size]的位置元素,并把值保存在x中,成功返回1,失败返回0*/
int ListGet(LinkedList* head, int i, DataType *x);
/*撤销单链表的空间*/
void ListDestory(LinkedList* head);
void ListInit(LinkedList* head)
{
head->next = NULL;
}
int ListNotEmpty(LinkedList* head)
{
if (head == NULL) {
printf("头结点为NULL\n");
return 0;
}
if (head->next == NULL)return 0;
else return 1;
}
int ListLength(LinkedList* head)
{
int i = 0;
LinkedList* p = head;
if (head == NULL) {
printf("头结点为NULL\n");
return 0;
}
while (p->next != NULL)
{
i++;
p = p->next;
}
return i;
}
int ListInsert(LinkedList* head, int i, DataType x)
{
LinkedList *p = head, *p1 = NULL;
if (head == NULL) {
printf("头结点为NULL\n");
return 0;
}
while (p != NULL && i--) //找到下标为i的结点的前一个结点
p = p->next;
if (i != -1) {
printf("插入参数i不合法\n");
return 1;
}
p1 = (LinkedList*)malloc(sizeof(LinkedList));
p1->data = x;
p1->next = p->next;
p->next = p1;
return 1;
}
int ListDelete(LinkedList* head, int i, DataType *x)
{
LinkedList *p = head, *p1 = NULL;
if (head == NULL) {
printf("头结点为NULL\n");
return 0;
}
while (p != NULL && i--) //找到下标为i的结点的前一个结点
p = p->next;
if (i != -1) {
printf("删除参数i不合法\n");
return 1;
}
p1 = p->next;
*x = p1->data;
p->next = p1->next;
free(p1);
}
int ListGet(LinkedList* head, int i, DataType *x)
{
LinkedList *p = head, *p1 = NULL;
if (head == NULL) {
printf("头结点为NULL\n");
return 0;
}
while (p != NULL && i--) //找到下标为i的结点的前一个结点
p = p->next;
if (i != -1) {
printf("参数i不合法\n");
return 1;
}
p = p->next;
*x = p->data;
return 1;
}
void ListDestory(LinkedList* head)
{
LinkedList *p, *p1 = NULL;
if (head == NULL) {
printf("头结点为NULL\n");
return ;
}
p = head->next;
if (p == NULL)return;
while (p->next != NULL)
{
p1 = p;
p = p->next;
free(p1);
}
free(p);
}
测试函数:
int i, x, size;
//也可用malloc动态申请内存,但是最后要自己调用free释放内存
LinkedList head;
ListInit(&head);
for (i = 0; i < 10; i++)
ListInsert(&head, i, i);
printf("将下标为5处的元素删除\n");
ListDelete(&head, 5, &x);
printf("被删除的元素为:%d\n", x);
printf("插入元素10到下标为5处:\n", x);
ListInsert(&head, 15, 15); //此行插入不合法
ListInsert(&head, 5, 10);
printf("将链表输出\n");
size = ListLength(&head);
for (i = 0; i < size; i++)
{
ListGet(&head, i, &x);
printf("%d ", x);
}
ListDestory(&head);
运行结果:
3.双向链表
实现代码:
//#pragma once //作为头文件时加上这行
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef int DataType;
typedef struct Node
{
DataType data;
struct Node *prior;
struct Node *next;
}DoublyList;
/*初始化链表,新定义的链表结点必须先初始化*/
void ListInit(DoublyList* head);
/*判断链表是否非空,非空返回1,空返回0*/
int ListNotEmpty(DoublyList* head);
/*返回链表元素个数*/
int ListLength(DoublyList* head);
/*在下标为i[0,size]的位置处插入一个元素x,位于该处及该处后的元素依次后移,成功返回1,失败返回0*/
int ListInsert(DoublyList* head, int i, DataType x);
/*将下标为i[0,size]的位置元素删除,并把值保存在x中,位于该处元素后的元素依次前移,成功返回1,失败返回0*/
int ListDelete(DoublyList* head, int i, DataType *x);
/*放问下标为i[0,size]的位置元素,并把值保存在x中,成功返回1,失败返回0*/
int ListGet(DoublyList* head, int i, DataType *x);
/*撤销单链表的空间*/
void ListDestory(DoublyList* head);
void ListInit(DoublyList* head)
{
head->prior = NULL;
head->next = NULL;
}
int ListNotEmpty(DoublyList* head)
{
if (head == NULL) {
printf("头结点为NULL\n");
return;
}
if (head->next == NULL)return 0;
return 1;
}
int ListLength(DoublyList* head)
{
DoublyList *p = head;
if (head == NULL) {
printf("头结点为NULL\n");
return;
}
int i = 0;
while (p->next != NULL)
{
i++;
p = p->next;
}
return i;
}
int ListInsert(DoublyList* head, int i, DataType x)
{
DoublyList *p = head, *p1 = NULL;
if (head == NULL) {
printf("头结点为NULL\n");
return;
}
while (p != NULL && i--) //找到下标为i的结点的前一个结点
p = p->next;
if (i != -1) {
printf("插入参数i不合法\n");
return 1;
}
p1 = (DoublyList*)malloc(sizeof(DoublyList));
p1->data = x;
/*下方代码 将新结点p1加到链表中,位于p后*/
p1->next = p->next;
p1->prior = p;
p->next = p1;
if (p1->next != NULL)p1->next->prior = p1; //若插入的元素下标不是链表尾
return 1;
}
int ListDelete(DoublyList* head, int i, DataType *x)
{
DoublyList *p = head, *p1 = NULL;
if (head == NULL) {
printf("头结点为NULL\n");
return;
}
while (p != NULL && i--) //找到下标为i的结点的前一个结点
p = p->next;
if (i != -1) {
printf("删除参数i不合法\n");
return 1;
}
p1 = p->next;
*x = p1->data;
/*下方代码 将p1从链表中删除*/
p->next = p1->next;
if (p1->next != NULL)p1->next->prior = p; //若插入的元素下标不是链表尾
free(p1);
return 1;
}
int ListGet(DoublyList* head, int i, DataType *x)
{
DoublyList *p = head, *p1 = NULL;
if (head == NULL) {
printf("头结点为NULL\n");
return;
}
while (p != NULL && i--) //找到下标为i的结点的前一个结点
p = p->next;
if (i != -1) {
printf("删除参数i不合法\n");
return 1;
}
p1 = p->next;
*x = p1->data;
/*下方代码 将p1从链表中删除*/
return 1;
}
void ListDestory(DoublyList* head)
{
DoublyList *p, *p1 = NULL;
if (head == NULL) {
printf("头结点为NULL\n");
return;
}
p = head->next;
if (p == NULL)return;
while (p->next != NULL)
{
p1 = p;
p = p->next;
free(p1);
}
free(p);
}
测试函数:
void test()
{
int i, x, size;
//也可用malloc动态申请内存,但是最后要自己调用free释放内存
DoublyList head;
ListInit(&head);
for (i = 0; i < 10; i++)
ListInsert(&head, i, i);
printf("将下标为5处的元素删除\n");
ListDelete(&head, 5, &x);
printf("被删除的元素为:%d\n", x);
printf("插入元素10到下标为5处:\n", x);
ListInsert(&head, 15, 15); //此行插入不合法
ListInsert(&head, 5, 10);
printf("将链表输出\n");
size = ListLength(&head);
for (i = 0; i < size; i++)
{
ListGet(&head, i, &x);
printf("%d ", x);
}
ListDestory(&head);
}
运行结果: