数据结构自学笔记——第一部分(线性表)
一.顺序表
顺序表主要构成是连续的存储单元,主要以数组的形式存储。
1.优点:
便于存取表中的任意元素
2.缺点:
需要一块连续的存储空间,插入删除需要移动大量元素,
3.代码:
# include <stdio.h>
# include <stdlib.h>
# include<string.h>
# include <malloc.h>
# define max 50
typedef struct linearlist
{
int a[max];
int len; // 确定顺序表的长度
}node;
void create_list(node& p)//创建一个顺序表
{
int i = 0;
while (i < p.len)
{
printf("请输入第%d元素的值:", i + 1);
scanf_s("%d", &p.a[i]);
i++;
}
}
void traverse_list(node& p)//顺序表的遍历
{
int i = 0;
while (i < p.len)
{
printf("第%d个元素值为%d\n", i + 1, p.a[i]);
i++;
}
}
void insert_list(node& p, int& pos, int& data)//顺序表的插入
{
int i = 0;
int len = p.len;
if (pos > 0 && pos <= len + 1)//防止插入位置错误
{
while (len > pos - 1)//找到要插入的位置,并将顺序表中原有数据从最后一位开始将数据不断向后移动一位
{
p.a[len] = p.a[len - 1];
len--;
}
p.a[len] = data;
p.len++;
}
else
{
printf("插入失败\n");
}
}
void dete_list(node& p, int& pos)//顺序表的删除
{
int len = p.len;
int data = p.a[pos - 1];
if (pos < len + 1 && pos > 0)
{
while (pos - 1 < len)//直接从要删除的位置的后一个元素开始向前覆盖即可
{
p.a[pos - 1] = p.a[pos];
pos++;
}
p.len--;
}
else
{
printf("删除失败!!!\n");
}
}
int main()
{
node p;
int pos;
int data;
printf("请输入初始长度:");
scanf_s("%d", &p.len);
create_list(p);
traverse_list(p);
printf("请输入插入的位置和值:");
scanf_s("%d%d", &pos, &data);
insert_list(p, pos, data);
traverse_list(p);
printf("请输入删除的位置:");
scanf_s("%d", &pos);
dete_list(p, pos);
traverse_list(p);
system("pause");
return 0;
}
二.链表
可以利用离散的存储空间建立一个链表。
1.优点:
不需要移动节点位置,直接进行数据的插入与删除。
2.缺点:
因为数据存储的不一定是连续的空间,所以不便于数据的存取。
需要存储指针域,所以所占内存要多一些。
3.代码:
/*创建一个线性单链表,并遍历输出,其数据域的值*/
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <malloc.h>
typedef struct node
{
int data;
struct node * pnext;
}node,*pnode;/*定义一个结构体,和一个结构体指针,便于构造动态内存*/
int main ()
{
int len;
int i,j = 0;
int a,b,c;
printf("请输入节点个数:");
scanf ("%d",&len);
pnode phead = (pnode)malloc(sizeof(node));/*头节点*/
pnode q = (pnode)malloc(sizeof(node));/*用于赋值的节点*/
q->pnext = NULL;
for(i =0;i < len;++i)
{
printf ("请输入第%d个节点的值:",i+1);
scanf("%d",&a);
pnode p = (pnode)malloc(sizeof(node));
p->data = a;
q->pnext = p;
while(j== 0)
{
++j;/*用于终止循环,并在输出链表时,作为节点位置*/
phead = q;/*将头节点链接到链表上*/
}
p->pnext = NULL;/*保持尾节点的指针域为空*/
q = p;
}
printf ("\n\n\n");
q = phead->pnext;
while(q)
{
printf ("请输出第%d个节点的值:%d\n",j++,q->data);
q = q->pnext;
}
/*链表的插入*/
i= 0;
printf ("请输入要插入的节点位置和值:");
scanf ("%d %d",&b,&a);
pnode q1 = (pnode)malloc(sizeof(node));/*移动的指针*/
pnode p1 = (pnode)malloc(sizeof(node));/*插入的节点*/
q1 = phead;
while(q1 != NULL && i < b-1) /*移动到要输出的位置的前一个位置*/
{
++i;
q1 = q1->pnext;
}
if(b > 0 && b < len+1)/*控制节点能存放在链表上*/
{
p1->data = a;
p1->pnext = q1->pnext;
q1->pnext = p1;
}
else
printf ("插入失败!!!\n");
/*输出插入后的链表*/
j = 1;
q1 = phead->pnext;
while(q1)
{
printf ("请输出第%d个节点的值:%d\n",j++,q1->data);
q1 = q1->pnext;
}
/*删除节点*/
printf ("请输入要删除的是第几个节点:");
scanf ("%d",&c);
i = 0;
q1 = phead;
pnode q2 = (pnode)malloc(sizeof(node));/*保存删除的值*/
while(q1 && i<c-1) /*移动节点到要删除的节点的前一个位置*/
{
++i;
q1 = q1->pnext;
};
if(i >= 0&& i < len + 1)
{
q2->pnext = q1->pnext;
q1->pnext = q1->pnext->pnext;
q2 = q2->pnext;
}
else
printf ("删除失败!!!\n");
/*输出删除后的链表*/
j =1;
pnode p3 = (pnode)malloc(sizeof(node));
p3 = phead->pnext;
while(p3)
{
printf("第%d个节点的值为:%d\n",j++,p3->data);
p3 = p3->pnext;
}
system ("pause");
}
scanf ("%d %d",&b,&a);
pnode q1 = (pnode)malloc(sizeof(node));/*移动的指针*/
pnode p1 = (pnode)malloc(sizeof(node));/*插入的节点*/
q1 = phead;
while(q1 != NULL && i < b-1) /*移动到要输出的位置的前一个位置*/
{
++i;
q1 = q1->pnext;
}
if(b > 0 && b < len+1)/*控制节点能存放在链表上*/
{
p1->data = a;
p1->pnext = q1->pnext;
q1->pnext = p1;
}
else
printf ("插入失败!!!\n");
/*输出插入后的链表*/
j = 1;
q1 = phead->pnext;
while(q1)
{
printf ("请输出第%d个节点的值:%d\n",j++,q1->data);
q1 = q1->pnext;
}
system ("pause");
}